You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js并发控制机制代码疑问:为何回调中需调用next()

代码示例

const tasks = ...
let concurrency = 2;
let running = 0;
let completed = 0;
let index = 0;
function next() {
    while (running < concurrency && index < tasks.length) {
        const task = tasks[index++];
        task(() => {
            if (completed === tasks.length) {
                return finish();
            }
            completed++;
            running--;
            next();
        });
        running++;
    }
}
next();

function finish() {
    console.log('All tasks are done');
}

用户疑问

我对上述Node.js并发控制代码存在疑问:tasks是需执行的异步任务数组,concurrency为最大并发数。程序启动时会取出前两个任务执行,当某个任务完成后会触发其回调函数。请问为何要在该回调中再次调用next()?回调执行完毕后,当前next()中的循环难道不会再次检查是否要取下一个任务处理吗?

解答

核心原因是第一次调用的next()里的循环会直接跑完,不会等待异步任务完成。

具体来说:

  • 程序启动调用next()后,会立刻进入while循环:先取第一个任务执行,running变为1;接着取第二个任务执行,running变为2。此时running不小于并发数2,循环直接结束,next()函数执行完毕退出,不会停在那里等任务完成。
  • 当某个异步任务完成触发回调时,之前的next()早就执行完了,根本不会再去检查循环条件。这时候必须手动调用next(),重新触发while循环:
    • 回调里先把running减1(比如从2变回1),此时running < concurrency的条件重新满足
    • 调用next()后,循环会检查是否还有未执行的任务(index < tasks.length),如果有就取出下一个任务执行,同时running加1,直到再次填满并发数或者任务全部取完

举个实际例子:假设tasks有3个任务。第一次next()执行完,前两个任务在跑,running=2,循环停了。等第一个任务完成,回调里running减到1,调用next(),循环会取出第三个任务执行,running变回2,循环再次结束。等剩下的任务完成时,回调里调用next(),循环会因为index等于tasks长度而不执行,直到最后一个任务完成触发finish()。

如果不在回调里调用next(),第一次next()跑完后,剩下的任务永远不会被执行——因为没人再去触发那个while循环了。

内容的提问来源于stack exchange,提问作者davaer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:42:40