aleksandrvin
@aleksandrvin

Вызов асинхронной функции из функционального map в JavaScript, как?

Есть массив объектов. Хочется для него выполнить map делая HTTP запрос для каждого объекта и возвращая новый объект-ответ.


Как это сделать, если для HTTP запросов используется модуль http из Node.js, который выполняет вызов асинхронно?
  • Вопрос задан
  • 3959 просмотров
Решения вопроса 1
Пригласить эксперта
Ответы на вопрос 4
dizballanze
@dizballanze
Software developer at Yandex
Модуль async вам в помощь. А именно — метод map.
Ответ написан
Комментировать
aleksandrvin
@aleksandrvin Автор вопроса
Не похоже, вкратце выглядит так:

inObjs.map(function /*ААА*/ (o) {
  var req = http.request(options, function (res) {
    var data = "";
    res.on('data', function (chunk) { data += chunk; };
    res.on('end', function () { /* Теперь надо объект data вернуть из лямбда-функции ААА */ ??? });
  });
  res.write(JSON.stringify(o));
  res.end();

  return /* Здесь надо дождаться того объекта data и вернуть его обратно в map */ ???
});


И параллельность или серийность работы map-а или eachSeries тут роли не играет.
Ответ написан
aleksandrvin
@aleksandrvin Автор вопроса
Вот, что в итоге получилось:

/**
 * Event-style map function with fun(e, consumer) as an element
 * transformation function that does not return modified object
 * but produce it to the ''consumer'' function instead.
 *
 * Result of the evmap-transformed objects will be transfered in
 * the ''callback'' call eventually.
 *
 * Main use is for maps with asynchronous transformation functions!
 */
function evmap(list, fun, callback) {
    function evmap(acc, list, fun) {
        if (list && 0 < list.length) {
            fun(list.shift(),
                function (result) {
                    acc.unshift(result);
                    evmap(acc, list, fun);
                });
        }
        else {
            callback(acc.reverse());
        }
    }
    evmap([], list, fun);
}

//// unit tests
exports.evmap_array = {
    'list': function (test) {
        evmap([1,2,3],
              function (e, c) { c(e + 10); },
              function (result) {
                  test.deepEqual(result, [11, 12, 13]);
                  test.done();
              });
    }
};
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы