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

JavaScript无Promise多文件加载:代码是否会漏触发allDone?

问题描述

我有一个FileLoader,使用方式如下:

const loader = new FileLoader();

loader.load(path1, data => { // onLoad function });
loader.load(path2, data => { // onLoad function });

我知道可以将该加载器包装成Promise,再用Promise.allSettled处理结果。但我仅需在所有文件加载完成时调用一个函数,无需检查失败情况,因此编写了如下代码:

let toload = num_files;
for(let i = 0; i < num_files; i++) {
  loader.load(path[i], data => {
    // process data
    toload--;
    if(toload == 0) allDone(); 
  }
}

考虑到加载的异步特性,这段代码是否会出现错误,导致错过toload == 0的条件?

回答

这段代码不会出现错过toload == 0的情况,原因很明确:

  • JavaScript的异步回调(这里的onLoad函数)运行在单线程的事件循环中,不存在多线程并发修改toload的竞态问题,每次toload--都是原子性的操作。
  • 最后一个完成加载的文件触发回调时,toload会被准确减到0,必然触发allDone()。

不过有两个细节需要注意:

  1. 如果num_files本身为0,循环不会执行,allDone()也不会被调用,建议在循环前补充判断:
let toload = num_files;
if (toload === 0) {
  allDone();
  return;
}
for(let i = 0; i < num_files; i++) {
  loader.load(path[i], data => {
    // process data
    toload--;
    if(toload == 0) allDone(); 
  });
}
  1. 若某个文件加载失败(比如网络错误、文件不存在),对应的onLoad回调不会执行,toload永远无法减到0,allDone()也就永远不会触发。如果你的业务需要在所有请求(无论成功失败)结束后执行allDone(),还是建议用Promise包装后配合Promise.allSettled,能完整捕获所有请求的结束状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:05:20