forEach с использованием генераторов в Node.js

Я использую модуль 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
});

Но этот код не работает, так как в функции есть выход. Если я напишу это:

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

Я тоже не получаю результат в переменной res. Я попытался использовать модуль " генератор-foreach ", но это не сработало.

Я знаю, что это моя нехватка знаний о языковой грамотности Node.js. Но можете ли вы, ребята, помочь мне найти способ, как это сделать?

Ответ 1

Спасибо, ребята, я сделал это, используя модуль " CO ". Благодарю.

var co = require('co');

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

EDIT: с последней версией CO вам понадобится co.wrap() для этого.

Ответ 2

Вы можете yield массивы, поэтому просто сопоставьте свои асинхронные обещания на другой карте

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

Ответ 3

Принимаемый ответ неверен, нет необходимости использовать библиотеку, массив уже является итерабельным.

Это старый вопрос, но поскольку он еще не имеет правильного ответа, и он появляется на первой странице в поиске Google ключевых терминов "итераторы и forEach", я отвечу на вопрос:

Нет необходимости перебирать массив по массиву, так как массив уже соответствует итерабельному API.

внутри вашего генератора просто используйте "yield * array" (обратите внимание на *) 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 *