循环中使用JavaScript Promise:如何判断所有Promise已完成?
解决JavaScript中等待所有Promise完成并合并结果的问题
我来帮你搞定这个问题!你现在的核心困扰是没把每个getDockData返回的Promise收集起来,所以没法用Promise.all来监听所有异步操作完成的时机。咱们一步步调整代码,让它符合你的需求:
问题分析
你原来的代码里,只是在循环中逐个调用getDockData,但没有保存每个调用返回的Promise对象,而且在then里逐个合并结果——这种方式没法知道什么时候所有Promise都执行完毕,因为每个异步请求的完成时间是不确定的。
解决方案步骤
- 收集所有Promise到数组:用
map遍历你的data.dock数组,把每个getDockData调用返回的Promise都存到一个数组里。 - 用Promise.all等待全部完成:
Promise.all会等待数组里所有Promise都成功resolve,或者在任何一个Promise reject时立即进入错误处理。 - 合并所有结果到一个大对象:当所有Promise都完成后,我们会得到一个包含所有resolve结果的数组,用
reduce把这些小对象合并成一个大对象。 - 添加错误处理:别忘记处理请求失败的情况,避免静默错误。
修改后的完整代码
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
相关产品推荐
相关产品推荐

