【问题标题】:NodeJS - Bluebird: wait for loop to completeNodeJS - Bluebird:等待循环完成
【发布时间】:2016-03-27 13:24:27
【问题描述】:

在解决本应简单的事情时遇到了一些困难。 我正在使用 NodeJS 和 mongodb,并且还安装了 Bluebird 以使用 Promise。

我有一个简单的 for 循环,我在其中创建了一堆随机名称,并将它们推送到一个数组中,如下所示:

const PlayerGenerator = () => {
   var playerArray = []
   for (var i = 0; i < 15; i++) {
      const player = new Player({
         name: 'Player' + Math.random() * 100
      })
      playerArray.push(player)
   }

   return playerArray

}

我想将所有这些名称写入我的数据库,但不确定如何正确设置我的 Promise,以便将每个玩家都写入我的数据库。

server.get('api/team/new', (req, res, next) => {
    const player = PlayerGenerator()
    // This array contains 15 players with the exact same name.
})

从我在这里的不同线程中读到的内容来看,promises 似乎是解决这个问题的最佳方法,但就像我上面提到的,不确定如何设置它,正在寻找一些建议。

【问题讨论】:

  • 为什么你认为 promise 会帮助你? Promise 是非常通用的东西,用于将功能与异步操作(如 XHRequests)链接起来。问题出在哪里?您无法写入数据库吗? 'const PlayerGenerator' 看起来也是完全同步的,在这里使用 Promise 是没有意义的。另外,如果您只是要将这些数据写入数据库,为什么要使用“const”?此外,在 ES6+node 中几乎完全实现了 Promise,为什么还要使用 Bluebird 之类的库来过度复杂化呢?
  • 更简洁一点“这里没有异步代码”。所以“也许”你的 Player 对象需要在数据库中实际创建,并且你只想在它们实际创建后返回。这就是你在这里问的吗?因为new Player() 可能不是异步方法。当然,除非你隐瞒了我们不知道的事情。我的“猜测”是这只是一个猫鼬模型参考。所以不是异步的。然而!

标签: javascript node.js mongodb mongoose bluebird


【解决方案1】:

我真的认为你这样做是错误的,因为他们似乎是一种更简单和合乎逻辑的方法来处理你似乎在思考的东西。

你真正想做的只是“在数据库中创建 15 个随机命名的玩家”,并避免使用更好的方法来获得唯一的随机名称(因为当前的方法不是“唯一”随机的) ,您真正需要做的就是将一组普通对象直接传递给Player.create(),因为您在这方面的历史表明您无论如何都在使用猫鼬:

Player.create(
  Array.apply(null,Array(15)).map(() => {
    return { "name": "Player" + Math.floor(Math.random() * 100) }
  })
).then((players) => {
  console.log(players)
});

这只会为您提供如下输出:

[ { _id: 56f7488242727e6c308f79eb, name: 'Player87', __v: 0 },
  { _id: 56f7488242727e6c308f79ec, name: 'Player29', __v: 0 },
  { _id: 56f7488242727e6c308f79ed, name: 'Player81', __v: 0 },
  { _id: 56f7488242727e6c308f79ee, name: 'Player52', __v: 0 },
  { _id: 56f7488242727e6c308f79ef, name: 'Player12', __v: 0 },
  { _id: 56f7488242727e6c308f79f0, name: 'Player93', __v: 0 },
  { _id: 56f7488242727e6c308f79f1, name: 'Player69', __v: 0 },
  { _id: 56f7488242727e6c308f79f2, name: 'Player88', __v: 0 },
  { _id: 56f7488242727e6c308f79f3, name: 'Player81', __v: 0 },
  { _id: 56f7488242727e6c308f79f4, name: 'Player48', __v: 0 },
  { _id: 56f7488242727e6c308f79f5, name: 'Player38', __v: 0 },
  { _id: 56f7488242727e6c308f79f6, name: 'Player82', __v: 0 },
  { _id: 56f7488242727e6c308f79f7, name: 'Player47', __v: 0 },
  { _id: 56f7488242727e6c308f79f8, name: 'Player85', __v: 0 },
  { _id: 56f7488242727e6c308f79f9, name: 'Player26', __v: 0 } ]

这似乎是最有意义的,因为它实际上只是对数据库的一次调用,因为 MongoDB 允许您指定多个文档以插入到单个语句中。

当然,如果您只是想使用 Promise 解析,那么只需使用 Promise.all(),这同样不需要在此处包含 Bluebird,特别是如果您已经在使用 ES6 结构运行。

只需从.create() 返回Promise,然后稍后再解析:

  var playerPromises = Array.apply(null,Array(15)).map(() => {
    return Player.create({ "name": "Player" + Math.floor(Math.random() * 100) });
  });

  Promise.all(playerPromises).then((players) => {
      console.log(players);
  });

所以在这种情况下,您只需使用 .create() 返回的 Promise 并将每个解析为结果数组。但它实际上是在写入数据库“15 次”,而您本可以只发送 “一个” 请求。

对于我的两分钱,只需将您想要创建的东西的数组直接提供给.create()。虽然有解决一系列承诺的用例,但这确实不是最佳解决方案。

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多