节点js中的嵌套asynchronousmongoDB调用

我有一个相当简单的问题,但我找不到一个优雅的解决scheme来解决这个问题。 在下面的代码中,我有两个对mongo数据库的嵌套调用。 我使用Monk来pipe理我的电话。 问题是:嵌套插入之前可能会发生for循环(1)循环。 所以下一个find(2)指令没有find最后一个插入的动作。

呼叫顺序是1-2-2-2-3-3-3(对于大小为3的动作列表)。 所以我所有的数据都被插入。

我的目标是有呼叫订单1-2-3-2-3-2-3

你有没有任何线索如何pipe理这样的问题,而不是在我的数据库发现一个大的和pipe理我的列表服务器端? (获取所有的数据,使自己的search,这是非常可怕的做,插入我想要的元素,然后把它推到数据库…)

for (var action of actionList)//(1) { collectionActions.find(//(2) {eventid : action.eventid}, function(e,actionsFound) { if (actionsFound.length == 0) { collectionActions.insert(action, function(err, result)//(3) { console.log("insert action : " + action._id); }) } } ) } 

原生的Promise对象有一个可以用来帮助的all方法。

假设find是一个合规的承诺,下面的代码将通过map将数组中的所有操作排队,并且将返回每个action的承诺,最终将消息返回到最后的all

几个注意事项:你的代码,因为它吞噬了所有可能发生的错误(我不知道这是你想要的); 这也假设insert返回一个承诺。

 Promise.all([ // Iterate over actionList actionList.map(function(action) { // returns a promise with a then already attached return collectionActions.find({ eventid: action.eventid }).then(function(e, actionsFound) { if (actionsFound.length == 0) { // returns another promise that will resolve up to outer promises return collectionActions.insert(action, function(err, result) { // Finally resolve a value for outer promises return 'insert action : ' + action._id; }); } else { // A different value to resolve with if the above promise // is not required return 'some other message for ' + action._id; } }); }) ]).then(function(results) { // Log out all values resolved by promises console.log(results); }); 

更新:在澄清这个问题之后,听起来好像你只需要将承诺链接在一起,而不是并行地运行它们。

 // Iterate over actionList actionList.reduce(function(promise, action) { // Chain promises together return promise.then(function(results) { return collectionActions.find({ eventid: action.eventid }).then(function(e, actionsFound) { if (actionsFound.length == 0) { // returns another promise that will resolve up to outer promises return collectionActions.insert(action, function(err, result) { // Finally resolve a value for outer promises return results.push('insert action : ' + action.sourceName); }); } else { // A different value to resolve with if the above promise // is not required return results.push('some other message for ' + action.sourceName); } }); }); }, Promise.resolve([])).then(function(results) { // Log out all values resolved by promises console.log(results); }); 

我终于得到了我的解决scheme,通过使用recursion函数。

 var currentIndex = 0; var searchAndInsert = function(actionList) { var action = actionList[currentIndex]; if (typeof actionList[currentIndex] != "undefined") { collectionActions.find( {eventid : action.eventid}, function(e,actions) { console.log("find ended") if (actions.length == 0) { collectionActions.insert(action, function(err, result) { console.log("insert action : " + action.sourceName); currentIndex++; if (typeof actionList[currentIndex] != "undefined") searchAndInsert(actionList); }) } else { currentIndex++; if (typeof actionList[currentIndex] != "undefined") searchAndInsert(actionList); } } ) } };