我正在尝试创建一个按结果顺序返回结果的承诺链,因为这对我的应用程序很重要。但是,尽管进行了许多尝试,但由于输出resultArray
的返回却交换了一些数据点,我仍在挣扎中,这使下游处理更加麻烦。这就是我目前所拥有的(在
Promise.all(data.map( (dataPoint) => {
return new Promise( (resolve, reject) => {
doSomething(dataPoint).then( (result) => {
resultArray.push(result);
resolve();
});
})
})).then( () => {
res.status(201).json({"result": resultArray});
});
我也尝试过以下模式,但是这只会返回[]作为promise。所有人似乎都没有等待诺言按预期完成:
let p = Promise.resolve();
data.forEach(dataPoint => {
p = p.then( () => {
getElevation(dataPoint, options).then( (result) => {
resultArray.push(result);
});
});
});
Promise.all([p]).then( () => {
res.status(201).json({"result": resultArray});
});
更新
尽管回答了所写的问题,但我现在意识到,接受的答案并不等待每个承诺在下一个承诺发布之前就返回。它会映射它们,以使输出按正确的顺序排列,但是我需要每个调用都了解最后一个-如何成功实现此目的?
答案 0 :(得分:3)
如果要按顺序获取数据,请不要使用forEach
和[].push
。将诺言添加到数组中,并将该诺言数组传递到Promise.all
,这将为您保留订单。
您的let p = Promise.resolve()
行也没有任何意义,只是在代码中增加了噪音。
使用.map
获取getElevation
承诺的数组,并将其传递给Promise.all
,当它解析结果时,其顺序将与data
数组相同。 / p>
const promises = data.map(dataPoint => getElevation(dataPoint, options));
Promise.all(promises).then(result => {
res.status(201).json({ result });
});
答案 1 :(得分:0)
如果希望每个承诺在下一个承诺之前完全解决,则可以使用async/await模式。这样,每个呼叫都可以访问先前呼叫的所有结果。
async function run(options) {
const results = [];
for(let dataPoint of data) {
const result = await getElevation(dataPoint, options);
results.push(result);
}
return results;
}
run(options).then(result => {
res.status(201).json({ result });
});