我有一段代码:
const finalPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("finalPromise");
}, 1000);
})
const obj = {
nested: {
a: 1,
b: 2
}
}
const p1 = Promise.resolve(3);
const p2 = Promise.reject(22);
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 3000);
});
new Promise(res => {
for(let i=0; i < 3; i++) {
if(i===0) {
p3.then(r => {
obj.nested.a = 3;
console.log(r)
}).catch(console.log)
}
if(i==1) p2.then(console.log).catch(console.log);;
if(i==2) p1.then(console.log).catch(console.log);
}
res(true); // this won't wait until all promises resolved/rejected
})
.then(() => finalPromise).then(r => console.log(`final ${r}, ${JSON.stringify(obj)}`)) // here we'll get obj with a = 1
.catch(e => console.log(`err ${e}`));
这段代码运行的结果如下:
[LOG]: 3
[LOG]: 22
[LOG]: "final finalPromise, {"nested":{"a":1,"b":2}}"
[LOG]: "foo"
所以我的问题是 - 我们能否以某种方式重写代码,以便只有在
then
内的所有承诺都已解决或拒绝(也应算作已解决)之后才能到达最后一个 for loop
?我知道这可以用 async/await
来完成,但由于某种原因被禁止。
我尝试使用 Promise.all
但找不到将 rejected
也算作 resolved
的方法。
可以按照 Yousaf 的建议使用
Promise.allSettled
或 Promise.all(promises).finally(...)
来实现所需的行为。
const promises = [];
for(let i=0; i < 3; i++) {
if(i===0) {
promises.push(p3.then(r => {
obj.nested.a = 3;
}).catch(console.log))
}
if(i==1) promises.push(p2.then(console.log).catch(console.log));
if(i==2) promises.push(p1.then(console.log).catch(console.log));
}
// Promise.allSettled(promises).then() - this way is also a valid option
Promise.all(promises).finally(() => finalPromise).then(r => console.log(`final ${r}, ${JSON.stringify(obj)}`)) // Now here we'll get obj with a = 3
.catch(e => console.log(`err ${e}`));
和日志:
[LOG]: 3
[LOG]: 1337
[LOG]: "foo"
[LOG]: "final ,,, {"nested":{"a":3,"b":2}}"