【问题标题】:forEach using generators in Node.jsforEach 在 Node.js 中使用生成器
【发布时间】:2014-09-06 16:25:18
【问题描述】:

我正在使用Koa.js 框架和Mongoose.js 模块。

通常要从 MongoDB 中获取结果,我的代码如下:

var res = yield db.collection.findOne({id: 'my-id-here'}).exec();

但我需要为名为“items”的数组的每个元素执行这一行。

items.forEach(function(item) {
  var res = yield db.collection.findOne({id: item.id}).exec();
  console.log(res)  // undefined
});

但是这个代码没有运行,因为 yield 在函数中。如果我这样写:

items.forEach(function *(item) {
  var res = yield db.collection.findOne({id: item.id}).exec();
  console.log(res)  // undefined
});

我也没有在 res 变量中得到结果。我尝试使用“generator-foreach”模块,但效果不佳。

我知道这是我对 Node.js 的语言素养缺乏了解。但是你们能帮我找到一种方法吗?

【问题讨论】:

  • 你对generator-foreach做了什么尝试?
  • 我刚刚将 forEach 替换为 generator-foreach。其余代码相同。你能修改我的代码 sn-p 并确保它正常工作吗?

标签: node.js foreach mongoose generator koa


【解决方案1】:

谢谢大家,我已经使用“CO”模块完成了这项工作。谢谢。

var co = require('co');

items.forEach(co(function* (item) {
  var img = yield db.collection.findOne({id: item.id}).exec();
}));

编辑:使用最新版本的 CO,您需要 co.wrap() 才能使其工作。

【讨论】:

  • 这不起作用,因为 item === items 当它被 co() 包裹时
  • 如果您使用标准 for 循环 for (x=0;x<items.length;x++),它会起作用,因为没有回调,因此您可以使用 yield 而无需将其包装在另一个 co 中。
  • 我做了同样的后记。很好的找到它。谢谢。
  • co 发生了一些变化。现在你需要 co.wrap() 然后这个例子有效
  • @az_ 的评论是解决方案。包含在 co() 中的 forEach 和 anoy 函数似乎不起作用,要使其正常工作,您需要改用 for 循环
【解决方案2】:

您可以yield 数组,因此只需将您的异步承诺映射到另一个地图中

var fetchedItems = yield items.map((item) => {
   return db.collection.findOne({id: item.id});
});

【讨论】:

  • 这要简单得多,应该是公认的答案。
【解决方案3】:

接受的答案是错误的,不需要使用库,数组已经是可迭代的。

这是一个老问题,但由于它还没有正确答案,而且它出现在谷歌搜索关键术语“迭代器和 forEach”的第一页上,我将回答这个问题:

没有必要对数组进行迭代,因为数组已经符合可迭代 API。

在您的生成器中,只需使用“yield* 数组”(注意 * ) yield* 表达式用于委托给另一个生成器或可迭代对象

例子:

let arr = [2, 3, 4];

    function* g2() { 
      yield 1;
      yield* arr;
      yield 5;
    }

    var iterator = g2();

    console.log(iterator.next()); // { value: 1, done: false }
    console.log(iterator.next()); // { value: 2, done: false }
    console.log(iterator.next()); // { value: 3, done: false }
    console.log(iterator.next()); // { value: 4, done: false }
    console.log(iterator.next()); // { value: 5, done: false }
    console.log(iterator.next()); // { value: undefined, done: true }

有关示例和深入信息,请访问: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-21
    • 2015-12-16
    • 2015-09-22
    • 2015-05-12
    • 2016-01-26
    • 2014-01-15
    • 2014-07-06
    • 2012-09-28
    相关资源
    最近更新 更多