我有一个Promise.all,它执行映射在数组输入上的异步函数,如果它不是null,然后将数据解析为先前定义的Promise:
Promise.all((inputs || []).map(input => {
return new Promise((resolve, reject) => {
someAsyncFunc(input)
.then(intermediateOutput => {
someOtherAsyncFunc(intermediateOutput )
.then(output => {
return Promise.resolve(output )
})
.catch(reason=> {
return Promise.reject(reason)
})
})
.catch(reason => {
return Promise.reject(reason);
})
})
.then(outputs => {
resolve(outputs)
})
.catch(reason => {
reject(reason)
})
}))
即使someAsyncFunc完成其工作,我也只获得空输出。如何让Promise.all等待内部的承诺完成异步工作?
答案 0 :(得分:3)
不仅仅是
return Promise.all((inputs || []).map(input =>
somePromiseFunc(input).then(someOtherPromiseFunc)
);
工作?
您第一次没有使用Promise.all
,因为它将一组承诺作为输入,而不是(resolve, reject) => { ... }
Promise.all
就会被拒绝,所以你不需要尝试围绕catch(error => reject(error)
做一些事情
示例:
const somePromiseFunc = (input) => new Promise((resolve, reject) => {
setTimeout(() => {
if (input === 0) { reject(new Error('input is 0')); }
resolve(input + 1);
}, 1000);
});
const someOtherPromiseFunc = (intermediateOutput) => new Promise((resolve, reject) => {
setTimeout(() => {
if (intermediateOutput === 0) { reject(new Error('intermediateOutput is 0')); }
resolve(intermediateOutput + 1);
}, 1000);
});
const f = inputs => {
const t0 = Date.now()
return Promise.all((inputs || []).map(input => somePromiseFunc(input).then(someOtherPromiseFunc)))
.then(res => console.log(`result: ${JSON.stringify(res)} (after ${Date.now() - t0}ms)`))
.catch(e => console.log(`error: ${e} (after ${Date.now() - t0}ms)`));
};
f(null)
// result: [] (after 0ms)
f([1, 0])
// error: Error: input is 0 (after 1001ms)
f([1, -1])
// error: Error: intermediateOutput is 0 (after 2002ms)
f([1, 2])
// result: [3,4] (after 2002ms)
答案 1 :(得分:2)
请参阅jfriend的评论。
someAsyncFunc
和someOtherAsyncFunc
是正确返回承诺的函数
像return new Promise(/*...*/);
这没用:
.then(output => {
return Promise.resolve(output )
})
阅读Promise文档
相同
.catch(reason=> {
return Promise.reject(reason)
})
承诺已经拒绝,你不需要抓住并拒绝自己
确保Promise是可链接的,你需要返回Promise
// ...
return new Promise((resolve, reject) => {
if(inputs == null)
resolve([]);
else {
Promise.all(inputs.map(input => {
return someAsyncFunc(input)
.then(someOtherAsyncFunc)
}))
.then(resolve)
.catch(reject)
}
});
请注意,我宁愿不为Promise.all内联制作arry,它会增加视觉上的混乱:
return new Promise((resolve, reject) => {
if(inputs == null)
resolve([]);
else {
const myPromises = inputs.map(input => {
return someAsyncFunc(input)
.then(someOtherAsyncFunc)
});
Promise.all(myPromises)
.then(resolve)
.catch(reject)
}
});
如果你犯了其他错误,它可能仍会失败。