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

循环中使用JavaScript Promise:如何判断所有Promise已完成?

解决JavaScript中等待所有Promise完成并合并结果的问题

我来帮你搞定这个问题!你现在的核心困扰是没把每个getDockData返回的Promise收集起来,所以没法用Promise.all来监听所有异步操作完成的时机。咱们一步步调整代码,让它符合你的需求:

问题分析

你原来的代码里,只是在循环中逐个调用getDockData,但没有保存每个调用返回的Promise对象,而且在then里逐个合并结果——这种方式没法知道什么时候所有Promise都执行完毕,因为每个异步请求的完成时间是不确定的。

解决方案步骤

  1. 收集所有Promise到数组:用map遍历你的data.dock数组,把每个getDockData调用返回的Promise都存到一个数组里。
  2. 用Promise.all等待全部完成:Promise.all会等待数组里所有Promise都成功resolve,或者在任何一个Promise reject时立即进入错误处理。
  3. 合并所有结果到一个大对象:当所有Promise都完成后,我们会得到一个包含所有resolve结果的数组,用reduce把这些小对象合并成一个大对象。
  4. 添加错误处理:别忘记处理请求失败的情况,避免静默错误。

修改后的完整代码

let data = JSON.parse(body);
// 1. 收集所有Promise到数组中
const promiseArray = data.dock.map(item => getDockData(item.url, user_token));

// 2. 等待所有Promise完成,处理结果或错误
Promise.all(promiseArray)
  .then(resultsArray => {
    // 3. 把结果数组合并成一个大对象
    const compedObj = resultsArray.reduce((mergedObj, currentItem) => {
      return {...mergedObj, ...currentItem};
    }, {});
    
    // 这里就是所有Promise完成后的操作,比如使用合并好的compedObj
    console.log('所有数据合并完成:', compedObj);
    // 执行你需要的后续逻辑...
  })
  .catch(error => {
    // 处理任何一个请求失败的情况
    console.error('有请求出错了:', error);
  });

function getDockData(url, token) {
  return new Promise((resolve, reject) => {
    var options = {
      url: url,
      headers: {
        'authorization': `bearer ${token}`,
        'user-agent': /* 你的应用信息 */
      }
    };

    function callback(error, response, body) {
      if (!error) {
        let data = JSON.parse(body);
        let obj = {};
        switch(data.title) {
          case "ToDos": 
            obj = {todos: data.todos_count}; 
            break;
          case "Messages": 
            obj = {messages: data.messages_count}; 
            break;
          // 新增默认情况,避免无匹配时返回空对象
          default:
            obj = {};
        }
        resolve(obj);
      } else {
        // 把具体错误信息传入reject,方便排查
        reject(`请求失败:${error}`);
      }
    }

    Request(options, callback);
  });
}

关键细节说明

  • 用map代替for循环:更简洁,也能直接生成Promise数组,不需要手动维护索引和数组。
  • Promise.all的特性:只要数组中有一个Promise reject,整个Promise.all就会立即进入catch,所以如果你的业务允许部分失败,可以考虑用Promise.allSettled来处理所有结果(包括成功和失败)。
  • reduce合并对象:比你原来逐个合并的方式更高效,因为它是一次性处理所有结果,而不是每次Promise完成都修改compedObj。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:30:18