协程
协程是一种基于线程之上,但又比线程更加轻量级的存在。对内核来说具有不可见性。
一个进程可以有多个线程。一个线程可以有多个协程。
generator函数
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 result2 = funG()
result2.next() // 1
result2.next() // 2
通过自动执行器去自动执行generator解决异步问题
所谓的自动执行,其实就是利用迭代器的每次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也是加分项!