怎样才能保证解决与回调的多个层中的所有数据的NodeJS
假设我有使用承诺的NodeJS下面的源代码(连接3件藏品MongoDB的,好了,这并不重要)怎样才能保证解决与回调的多个层中的所有数据的NodeJS
function getData(){
return new promise((resolve, reject) => {
var dataArray = [];
getCollection1().then((rows1) => {
getCollection2().then((rows2) => {
var val = someDataProcessingFunction(rows1, rows2);
dataArray.push(val);
resolve(dataArray);
}, (err) => {
reject(err);
}
}, (err) => {
reject(err);
});
getCollection3().then((rows3) => {
rows3.forEach((row3) => {
dataArray.push(row3);
});
resolve(dataArray);
}, (err) => {
reject(err);
});
});
}
的问题是,有多个地方dataArray推,但我不知道什么时候所有的推动完成。以便我不知道何时解决,将数据返回给用户,例如,通过response.send以express方式。至于上面的代码,当我使用多次解析时,我只会得到部分返回的数据。
我能想出两种解决方法,既不好。一个是围绕setTimeout中的所有解析,这意味着我必须延迟对用户的响应。
另一种方法是在开始时计算所有的推送时间,每次按一个项目时减1。当时间为0时,解决问题。但在进行实际循环之前往往难以计算数字。
有没有更好的解决方案?谢谢你,爱你:)
首先,避免使用Promise
constructor antipattern并改用返回值!对于多层异步功能,只需使用多层承诺。要一次等待多用,使用Promise.all
:
function getData(){
return Promise.all([
getCollection1(),
getCollection2(),
getCollection3()
]).then(([rows1, rows2, rows3]) => {
return [someDataProcessingFunction(rows1, rows2)].concat(rows3);
});
}
非常感谢。我不知道Promise.all。但经过1天的学习,我仍然认为它不能解决我的问题,因为我有多个并行分支,有些分支有子分支,都可能产生部分结果数据。我不知道何时以及如何返回。然后功能。 Promise.all只解决了第一个并行层 – vdonkey
之后,我发现了另一个解决方案:ES7 async/await。我可以使用async/await编写“真正的”同步功能。这样的生活更容易。我下载了NodeJS 8.4.0,在我的Ubuntu 16.04上使用新的async/await。它的工作和我的代码缩短了很多 – vdonkey
你可以任意嵌套这些。为每个子结果做出承诺。在子结果数组上调用'Promise.all'。在'.then()'里面做这个子计算,再次返回一个promise。 [总是从每个函数返回](https://stackoverflow.com/a/25756564/1048572)。 – Bergi
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all –
注意'then'回调只执行一次,所以我不明白为什么你有'dataArray',因为你只会推两次。 – trincot
同样,你不能两次解决承诺。第二次调用'resolve'将不起作用。 – trincot