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

Promise.all处理所有Promise(成功/失败)的代码问题排查

问题分析与修复方案

嘿,我来帮你搞定这个问题!你已经猜到核心原因是map函数里忘记返回Promise了,咱们来详细拆解下为什么这会导致问题,以及怎么修复。

核心问题:map函数未返回处理后的Promise

你在Promise.all(a.map((p) => { ... }))里的map回调,只是调用了p.catch()但没有把这个处理后的Promise返回出去。这就导致map最终生成的数组里全是undefined——因为函数没有明确返回值时默认返回undefined。

而Promise.all接收一组Promise(或者可迭代的非Promise值),如果传入的是undefined数组,它会直接进入resolved状态,并且results就是全undefined的数组,这和你看到的现象完全一致。

更关键的是,只有让map返回p.catch()生成的新Promise,才能让Promise.all真正等待所有原Promise(不管成功还是失败)处理完成:因为p.catch()会捕获原Promise的reject,并返回一个resolved状态的Promise(除非catch里再抛出错误),这样Promise.all就能等到所有Promise都进入resolved状态后再执行后续逻辑。

修复后的完整代码

我把关键修改处用注释标出来了:

console.clear();
$(document).ready(function () {
 var url = "https://httpbin.org/get?";
 a = [];
 a.push(new Promise(function (resolve, reject) {
 $.get(url + Math.random()).then((res) => resolve()).fail(() => { reject(); });
 }));
 a.push(new Promise(function (resolve, reject) {
 $.get(url + Math.random()).then((res) => resolve()).fail(() => { reject(); });
 }));
 var mr = getPromise();
 function getPromise() {
 var promise = new Promise(function (resolve, reject) {
 window.setTimeout(function () { reject(); }, 1000);
 });
 return promise;
 }
 a.push(mr);
 a.push(new Promise(function (resolve, reject) {
 $.get(url + Math.random()).then((res) => resolve()).fail(() => { reject(); });
 }));
 a.push(new Promise(function (resolve, reject) {
 $.get(url + Math.random()).then((res) => resolve()).fail(() => { reject(); });
 }));
 Promise.all(a.map((p) => {
 // 关键修改:返回catch处理后的Promise
 return p.catch((e) => {
 console.log("failed promise catch");
 });
 }))
 .then((results) => {
 console.log("##### should be final call ####");
 })
 .catch((e) => {
 console.log("final catch block executed");
 });
}); // ready end
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

额外优化建议(可选)

其实jQuery的$.get本身就返回一个兼容Promise的Deferred对象,你不需要再额外包一层new Promise,可以简化成这样:

// 替代原来的a.push(new Promise(...))写法
a.push($.get(url + Math.random()).then(() => {}).fail(() => Promise.reject()));

这样代码更简洁,也减少了不必要的Promise嵌套。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:43:43