本文来自于 <你不知道的Javascript> 学习笔记
生成器函数返回的是迭代器,在内部每个yield
的是promise
,当迭代器启动后,it.next().value
就是promise
,在promise
的then
中不断的递归执行 it.next(data)
方法,其中data
就是每个promise resolve
的值.
es7
的async
和await
相当于就是把这个流程写进了语法层面.async
函数相当于 生成器,await
相当于 yield
function foo() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('一层 promise resolve的值')
}, 1000)
})
}
function bar() {
return new Promise(resolve => {
setTimeout(() => {
resolve(new Promise(resolve => {
resolve('两层 promise resolve 的值')
}))
}, 1000)
})
}
function syncFn() {
return '同步函数返回的值'
}
// 这里相当于 async 函数
function* main() {
try {
console.log('1', yield foo()) // yield 相当于 await
console.log('2', yield bar())
} catch (err) {
console.log(err)
}
console.log('3', yield syncFn())
return 'inner value'
}
// 该函数用于自动执行 generator 函数返回的迭代器的 next 方法,直到 done, 在 yield 后面的 promise 的回调中执行 it.next, 递归执行.
function runGenFn(genFn) {
const it = genFn()
return new Promise(resolve => {
// 递归执行迭代器,将 promise resolve 的值传递进生成器里的 yield
const _runIt = (it, data) => {
const { value, done } = it.next(data)
if (!done) {
toPlainPromise(value).then(_data => {
// console.log('hhh')
_runIt(it, _data)
})
} else {
toPlainPromise(value).then(_data => {
resolve(_data)
})
}
}
const isPromise = (v): v is Promise<any> => {
return Object.prototype.toString.call(v) == '[object Promise]'
}
// 解析多层 promise,返回只有一层的 promise
const toPlainPromise = (p) => {
const resolveNestPromise = (p, resolve) => {
if (isPromise(p)) {
p.then(value => {// 此处的value可能还是promise
resolveNestPromise(value, resolve)
})
} else {
resolve(p)
}
}
return new Promise(resolve => {
resolveNestPromise(p, resolve)
})
}
_runIt(it, undefined)
})
}
runGenFn(main).then(data => {
console.log('main 生成器返回的值::>>', data)
})