JavaScript协程示例疑问:调用coroutine后的执行逻辑困惑
理解这个JavaScript协程示例的执行流程
咱们一步一步拆解这个代码的执行过程,把每一步的逻辑理清楚:
第一步:启动协程
当你调用coroutine(function* () { ... })时,首先进入coroutine函数:
- 先执行
let gen = fn(),这里的fn就是你传入的那个生成器函数,这一步会创建一个生成器实例,但生成器函数内部的代码还没开始执行。 - 接着调用
doNext(),正式启动整个流程。
第二步:第一次执行生成器(获取帖子)
- 调用
doNext()时,参数data是undefined,执行let next = gen.next(data):- 这会启动生成器函数,执行到第一个
yield fetchPosts()的位置。 - 先调用
fetchPosts(),这个函数应该会返回一个Promise(用来异步获取帖子数据),然后yield会暂停生成器的执行,把这个Promise作为next.value返回,此时next.done是false(因为生成器还没执行完)。
- 这会启动生成器函数,执行到第一个
- 因为
next.done是false,所以执行next.value.then(doNext):意思是等fetchPosts()的Promise成功resolve后,把返回的帖子数据传给doNext函数,继续执行生成器。
第三步:拿到帖子数据,获取所有评论
当fetchPosts()的Promise成功拿到帖子数据(假设叫posts):
- 这个
posts会作为参数传给doNext,执行let next = gen.next(posts):- 生成器从之前暂停的
yield位置恢复执行,把posts赋值给let posts = yield ...这行的posts变量。 - 接下来执行
posts.map(post => fetchComments(post)),给每个帖子生成一个获取评论的Promise,得到一个Promise数组。 - 然后调用
Promise.all(promises),这个方法会返回一个新的Promise,当数组里所有Promise都resolve后,这个新Promise才会resolve。 - 遇到第二个
yield,生成器再次暂停,把Promise.all返回的Promise作为next.value返回,next.done还是false。
- 生成器从之前暂停的
- 再次执行
next.value.then(doNext),等待所有评论的Promise都完成。
第四步:拿到所有评论,完成流程
当Promise.all(promises)成功resolve,拿到所有评论的数组comments:
comments被传给doNext,执行let next = gen.next(comments):- 生成器恢复执行,把
comments赋值给let comments = yield ...这行的comments变量。 - 然后执行
displayComments(comments),完成生成器函数里的最后一行代码。
- 生成器恢复执行,把
- 这次
gen.next(comments)返回的next.done是true(因为生成器函数已经执行完毕),所以doNext函数不再继续执行,整个协程流程结束。
核心逻辑总结
这个coroutine函数其实是一个生成器自动执行器:它负责把异步操作(Promise)的结果,通过then(doNext)传递回生成器,让生成器从暂停的位置继续执行。这样原本需要嵌套回调的异步代码,就可以写成类似同步代码的线性结构,这也是早期用生成器模拟async/await的思路。
内容的提问来源于stack exchange,提问作者Mussé Redi
相关产品推荐
相关产品推荐

