基于《You Dont Know JS》伪代码的JS回调与异步执行流程疑问
《You Don't Know JS》异步/同步回调执行逻辑推导
示例伪代码如下:
doA( function1(){ doC(); doD( function2(){ doF(); }) doE(); }); doB();
异步场景(doA、doD为异步函数)
你之前的理解完全正确,执行顺序A -> B -> C -> D -> E -> F的逻辑如下:
- 主线程先调用异步函数doA,doA自身的异步逻辑(对应A操作)启动后立刻返回,不会阻塞主线程,传入的function1会被注册为异步回调,等A操作完成后推入任务队列
- 主线程继续执行后面的同步代码doB,B执行完成,此时主线程调用栈清空
- 事件循环从任务队列取出等待的function1执行:
- 先同步执行doC,C完成
- 调用异步函数doD,doD自身的异步逻辑(对应D操作)启动后立刻返回,传入的function2注册为回调,等D操作完成后推入任务队列
- 继续执行后面的同步代码doE,E完成,function1执行完毕,调用栈再次清空
- 事件循环取出任务队列里的function2执行,同步执行doF,F完成,整个流程结束
同步场景(doA、doD为同步函数)
执行顺序A -> C -> D -> F -> E -> B的逻辑和你猜测的一致,核心原因就是JS单线程下同步函数会阻塞调用栈,必须等当前调用栈所有代码执行完毕才会执行后续外层代码,具体推导:
- 主线程先调用同步函数doA,doA会先执行自身逻辑完成A操作,同步函数的回调不会进任务队列,而是立刻原地执行,所以直接进入function1的执行,doA整个执行完之前不会往下走执行doB
- function1内部先同步执行doC,C完成
- 调用同步函数doD,doD先执行自身逻辑完成D操作,立刻原地执行回调function2
- function2内部同步执行doF,F完成,function2执行完毕出栈,回到doD的上下文,doD执行完毕出栈,回到function1的上下文
- function1继续执行后面的同步代码doE,E完成,function1执行完毕出栈,回到doA的上下文,doA执行完毕出栈
- 主线程终于可以继续执行后面的同步代码doB,B完成,整个流程结束
内容的提问来源于stack exchange,提问作者Kwaku Biney
相关产品推荐
相关产品推荐

