【问题标题】:Nested asynchronous mongoDB calls in node js节点js中嵌套的异步mongoDB调用
【发布时间】:2016-12-26 19:48:29
【问题描述】:

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

调用顺序为 1-2-2-2-3-3-3(对于大小为 3 的 actionList)。所以我所有的数据都被插入了。

我的目标是调用顺序为 1-2-3-2-3-2-3

您是否知道如何管理此类问题,而无需在我的数据库上进行大量查找并在服务器端管理我的列表? (获取所有数据,让自己搜索,这很可怕,插入我想要的元素,然后将其全部推送到数据库......)

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);
                })
            }
        }
    )
}

【问题讨论】:

标签: node.js mongodb asynchronous callback


【解决方案1】:

本机 Promise 对象有一个 all 方法可以用来提供帮助。

假设find 是一个符合要求的承诺,以下代码将通过map 将数组中的所有操作排队,并且将为每个action 返回一个承诺,最终将消息返回到最终thenall

几点注意事项:您的代码会吞噬所有可能发生的错误(我不确定您是否想要);这也假设 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);
});

更新:在澄清问题之后,听起来您只需要将 Promise 链接在一起,而不是并行运行它们。

// 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);
});

【讨论】:

  • 很抱歉,它不起作用。我的第一张地图有 3 个具有相同事件 ID 的操作。其中 3 个已插入...我更新了我的问题,以确保我的需求很明确。
  • @strategesim 我明白了。您最初的问题对此有点不清楚。我已经更新了答案,以反映为满足您的限制而需要进行的更改。
【解决方案2】:

我终于得到了我的解决方案,通过使用递归函数。

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);
                }
            }
        )
    }
};

【讨论】:

    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2016-07-25
    • 2015-11-30
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2023-04-02
    • 2019-10-27
    相关资源
    最近更新 更多