带有 API 和数据库查询的 Node.js Promise Chain
Posted
技术标签:
【中文标题】带有 API 和数据库查询的 Node.js Promise Chain【英文标题】:Node.js Promise Chain with API and database query 【发布时间】:2016-05-26 14:14:40 【问题描述】:我对整个承诺业务很陌生,正在与他们一起尝试我的项目。 不,我需要查询一个外部 API,在响应中执行几个项目,用它们对我自己的数据库进行其他检查,当所有这些都完成后,需要自己解决整个承诺。 我还需要在标记点再次调用我的数据库并做出另一个承诺。这些是相互独立的,但“父”承诺只有在两者都解决时才会解决。 我在这里遇到了困难,可能需要一些关于将多个承诺与多个项目链接起来的一般解释。 也许我只是在这里理解了一些普遍错误的东西...... 到目前为止,这是我的代码(缩写为 ...):
'use strict';
import rp from 'request-promise';
import _ from 'lodash';
var Import =
init: function(user, options)
return new Promise((resolve, reject) =>
rp.get("...") // call to external API
.then((res) =>
...
resolve();
);
...
);
,
run: function()
return new Promise((resolve, reject) =>
...
rp.get(...) // call to external API
.then((res) =>
var events = JSON.parse(res).data;
var promises = [];
for (var i = 0; i < events.length; i++)
promises.push(new Promise((resolve, reject) =>
...
Location.findOneAndUpdateAsync(...)
.then((loc) =>
events[i].location = loc._id;
resolve();
)
.catch((err) =>
console.error(err);
reject();
);
// I need even another call to my database here later with another promise
));
return Promise.all(promises)
.then(() =>
console.log("all promises resolved");
resolve(events);
);
)
.catch((err) =>
console.error(err);
reject(err);
);
);
;
【问题讨论】:
将您的问题隐藏在代码中的 cmets 内无济于事...您还使用了典型的承诺“反模式”,即在您的循环中创建一个新的承诺已经创建了一个承诺的函数。 这些本来应该是一个补充,但我要改变它 首先,避免Promise
constructor antipattern。你的函数已经返回了 Promise。
听起来你在找Promise.all([onePromise, otherIndependentPromise]).then(whenBothAreDone)
@Kageetai 是您希望 inside 循环的两个调用吗?
【参考方案1】:
您可以通过不违反Promise constructor anti-pattern 来显着简化您的代码 - 您调用的函数已经返回承诺,因此您应该利用这些承诺。
然后,用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 ...
);
然后您只需要等待所有这些并返回您的 events
对象:
return Promise.all(promises.concat(promises2)).then(() => events);
不需要所有 .catch
块 - 您应该让错误向上传播。
如果(根据您的 cmets)这两个内部调用有依赖关系,您可以试试这个:
var promises = events.map(function(event)
return Location.findOneAndUpdateAsync(...)
.then((loc) =>
event.location = loc._id;
if (condition)
return XXXOtherFunctionReturningPromise();
);
);
[然后显然消除上面的.concat
调用]
【讨论】:
嗯,如果第一个(我仍然必须实现)调用(我自己database) 返回一个具体的答案? 可能很容易,但不是您要求的! ;-) 是的,我自己的错,只是重新考虑了整个过程...... X-) 我添加了一些内容,但现在重新阅读您的评论时,我不确定您的要求是什么。第一个呼叫是“循环中的第一个”,还是rp.get()
呼叫?
我的意思是我所做的 Location.findOneAndUpdateAsync()
应该是第一次调用我自己的数据库,之后我仍然需要另一个调用我的数据库以上是关于带有 API 和数据库查询的 Node.js Promise Chain的主要内容,如果未能解决你的问题,请参考以下文章
带有 Node JS 和 Sails JS 的 Facebook Graph API
如何在 Node.js 中使用带有 API 网关的 AWS Lambda 发送二进制响应? [复制]