协程是一种基于线程之上,但又比线程更加轻量级的存在。对内核来说具有不可见性。
一个进程可以有多个线程。一个线程可以有多个协程。
generator就是生成器函数。是协程在es6中的一个实现。它最大的特征就是可以交出函数的执行权。
generator函数的执行和传统的不一样,它的返回值是一个迭代器对象。
简单理解就是返回值是一个对象,有两个属性,一个是value,一个是done,vlaue就是返回的值,done就是是不是可以继续迭代。
generator的写法:
1.generator相对于普通函数在function后面多加了*号
2.在每个我们需要中断执行的语句前加了yield,通过yield来控制函数执行。也就是说他的返回值每次调用next只会执行第一个yield后面的代码,如果需要继续执行,需要调用返回的迭代器的next方法
如果没有yield了,会返回{value: undefined, done:true}
- function* funG() {
- yield console.log(1)
- yield console.log(2)
- yield console.log(3)
- }
- const result = funG()
- result.next() // 1
- result.next() // 2
所谓的自动执行,其实就是利用迭代器的每次next都会指向下一个迭代对象。
如果done 为true则表示没有下一个了。
所以我们利用判断done+递归,实现generator的自动执行。
- function* gen(){
- let url = 'xxxxx'
- let result = yield fetch(url) // fetch假设是一个ajax请求,返回的是一个promise对象
- console.log(result.value)
- }
- let g = gen() // g 是一个可迭代对象
- let result = g.next()
- // 自动执行函数
- function run (gen){
- let g = gen()
- function next(data){
- let result = g.next()
- if(result.done){
- return result.value
- }
- result.value.then(function(){
- return data.json()
- }).then(function(data){
- next(data)
- })
- }
- next()
- }
- run(gen)
其实generator在我们实际开发中比较不常见,因为他本身当时主要用于js 的异步解决方案,但是后来被更好的async await替代了,async await也是js异步的终极解决方案。但是generator独特的特性可以让我们在函数执行的过程中传递参数获取结果,使得函数调用变得更加灵活。
我们了解一下,对我们以后阅读源码,进阶都是很有帮助的,面试的时候除了async -await 之前再聊一聊generator也是加分项!