Javascript Node.js承诺链,带API和数据库查询

Javascript Node.js承诺链,带API和数据库查询,javascript,node.js,api,promise,Javascript,Node.js,Api,Promise,我对整个promises业务相当陌生,正在与他们一起尝试我的项目。 不,我需要查询一个外部API,在响应中执行几个项目,用它们对我自己的数据库进行其他检查,当所有这些检查完成后,需要自行解决整个承诺。 我还需要在标记点用另一个承诺再次调用我的数据库。它们相互独立,但“父”承诺只有在两者都解决时才能解决。 我在这里遇到了麻烦,可能需要一些关于用多个项目链接多个承诺的一般性解释。 也许我只是理解这里的一些普遍错误。。。 这是我目前的代码(缩写为…): “严格使用”; 从“请求-承诺”导入rp; 从“

我对整个promises业务相当陌生,正在与他们一起尝试我的项目。
不,我需要查询一个外部API,在响应中执行几个项目,用它们对我自己的数据库进行其他检查,当所有这些检查完成后,需要自行解决整个承诺。
我还需要在标记点用另一个承诺再次调用我的数据库。它们相互独立,但“父”承诺只有在两者都解决时才能解决。
我在这里遇到了麻烦,可能需要一些关于用多个项目链接多个承诺的一般性解释。
也许我只是理解这里的一些普遍错误。。。 这是我目前的代码(缩写为…):

“严格使用”;
从“请求-承诺”导入rp;
从“lodash”进口;
变量导入={
初始化:函数(用户、选项){
返回新承诺((解决、拒绝)=>{
rp.get(“…”/)调用外部API
。然后((res)=>{
...
解决();
});
...
});
},
运行:函数(){
返回新承诺((解决、拒绝)=>{
...
rp.get(…)//调用外部API
。然后((res)=>{
var events=JSON.parse(res).data;
var承诺=[];
对于(var i=0;i{
...
Location.findOneAndUpdateAsync(…)
。然后((loc)=>{
事件[i]。位置=loc.\u id;
解决();
})
.catch((错误)=>{
控制台错误(err);
拒绝();
});
//我以后还要再打一次电话到我的数据库,再答应一次
}));
}
回报承诺。全部(承诺)
.然后(()=>{
console.log(“所有承诺已解决”);
解决(事件);
});
})
.catch((错误)=>{
控制台错误(err);
拒绝(错误);
});
});
}
};

您可以大大简化代码,因为您调用的函数已经返回了承诺,因此您应该充分利用这些承诺

然后,使用
Array.prototype.map消除
for
/
push
循环的

var promises = events.map(function(event) {
    return Location.findOneAndUpdateAsync(...)
            .then((loc) => event.location = loc._id);
});
您说过要进行两组调用,但由于它们是独立的,您不妨使用另一个
.map
调用:

var promises2 = events.map(function(event) {
    return ...
});
然后,您只需等待所有这些并返回
事件
对象:

return Promise.all(promises.concat(promises2)).then(() => events);
不需要所有那些
.catch
块-您应该让错误向上传播

如果(根据您的评论)两个内部调用具有依赖关系,您可以尝试以下方法:

var promises = events.map(function(event) {
    return Location.findOneAndUpdateAsync(...)
           .then((loc) => {
               event.location = loc._id;
               if (condition) {
                   return XXXOtherFunctionReturningPromise();
               }
           });
});

[很明显,然后消除上面的
.concat
调用]

将您的问题隐藏在代码注释中没有任何帮助。。。您还使用了典型的承诺“反模式”,即围绕已创建承诺的函数在循环中创建新承诺。这些本来只是一个加法,但我要改变这一点,首先,避免。你的函数已经返回了承诺。听起来你在寻找
Promise.all([onePromise,otherIndependentPromise])。那么(当两个都完成时)
@Kageetai是不是你期望在该循环中进行两个调用?嗯,顺便说一句,这两个调用仍然依赖,我想完全跳过一个事件,如果第一个(我仍然需要实现)调用(我自己的数据库)返回一个特定的答案?可能很简单,但不是你要求的!;-)是的,我自己的错,只是重新考虑了一下整个过程。。。X-)我补充了一些东西,但现在重读你的评论,我不确定你想要什么。第一个调用是“循环中的第一个”,还是
rp.get()
调用?我指的是我所做的
Location.findOneAndUpdateAsync()
应该是对我自己的数据库的第一个调用,之后我还需要另一个对我的数据库的调用
var promises = events.map(function(event) {
    return Location.findOneAndUpdateAsync(...)
           .then((loc) => {
               event.location = loc._id;
               if (condition) {
                   return XXXOtherFunctionReturningPromise();
               }
           });
});