回调函数调用顺序困惑:异步nthPrime质数乘积代码解析
异步回调链式调用执行逻辑说明
首先明确nthPrime的核心行为:调用该函数时,它只会启动对应的质数计算异步任务,立刻返回,不会阻塞等待计算结果;只有当计算任务完成后,它才会主动调用你传入的callback函数,并把计算得到的质数作为参数传给callback。
你看到的参考代码,本质是用「回调嵌套」的方式保证两个异步计算按顺序执行,避免出现第二个质数都算完了,第一个质数还没拿到的情况。
逐段代码对应执行逻辑
我们顺着完整执行流一步步拆:
- 流程起点是手动调用
foo()foo内部只有一行代码nthPrime(100, a);:这行执行时,立刻启动「计算第100个质数」的异步任务,然后马上返回,foo执行完毕。这里传进去的函数a只是作为回调登记,这时候a根本不会执行。
- 后台异步计算完第100个质数后,
nthPrime会主动调用之前登记的回调a,把算好的第100个质数作为参数p传入,此时才开始执行a内部的代码:- 第一行
t = p;:这里的p就是刚算出来的第100个质数。因为等下还要启动第二个异步计算,等第二个计算完成的时候,a的函数栈早就销毁了,局部变量p会被回收,根本留不住值,题目允许用全局变量,所以把第一个质数结果存到全局变量t里暂存,方便后续计算用。 - 第二行
nthPrime(200, b);:和第一次调用nthPrime的逻辑完全一致——这行执行时立刻启动「计算第200个质数」的异步任务,然后马上返回,a执行完毕。这里传进去的函数b同样只是作为回调登记,不会立刻执行。
- 第一行
- 后台异步计算完第200个质数后,
nthPrime会主动调用之前登记的回调b,把算好的第200个质数作为参数p传入,此时开始执行b内部的代码:- 这里的参数
p就是刚算出来的第200个质数,之前存在全局变量t里的是第100个质数,两个值相乘t * p就是题目要求的两个质数的乘积,直接打印即可,整个流程结束。
- 这里的参数
完整时序清单
- 手动调用
foo(),进入同步执行段 foo内调用nthPrime(100, a),启动第100个质数异步计算任务,nthPrime立刻返回,foo执行结束- 后台非阻塞计算第100个质数,主线程不等待
- 第100个质数计算完成,触发回调
a(第100个质数值),进入第一段回调执行段 a中将第100个质数赋值给全局变量t暂存a内调用nthPrime(200, b),启动第200个质数异步计算任务,nthPrime立刻返回,a执行结束- 后台非阻塞计算第200个质数,主线程不等待
- 第200个质数计算完成,触发回调
b(第200个质数值),进入第二段回调执行段 b中读取全局变量t(存的第100个质数),和当前入参p(第200个质数)相乘,打印结果,流程结束
易混点澄清
- 怎么区分同步立即执行和异步延迟执行的代码:凡是你主动写
函数名(参数)直接调用的代码,都是在当前时序里同步立刻跑的;凡是你只把函数名作为参数传给其他异步函数、从来没有主动加括号调用的,都是异步延迟执行的,只会等异步任务完成后被异步函数触发。 - 为什么必须嵌套调用第二个
nthPrime:如果不在a里调用第二个nthPrime,而是在foo里连续写两行nthPrime(100,a)和nthPrime(200,b),两个异步任务会同时启动,你没法保证哪个回调先触发——很可能b先执行,这时候t还没被赋值,算出来的乘积就是错的。嵌套在回调里调用,就能保证第一个计算100%完成拿到结果了,才启动第二个计算。 - 为什么不用局部变量存第一个质数:两次回调是完全独立的两次函数调用,栈空间不共享,a的局部变量b根本访问不到,用全局变量是题目允许范围内最简单的跨回调传值方案。
内容的提问来源于stack exchange,提问作者hodondo
相关产品推荐
相关产品推荐

