#javascript #node.js #parallel-processing #nonblocking
#javascript #node.js #параллельная обработка #неблокирующий
Вопрос:
Я хочу параллельно выполнить несколько запросов http get, сопоставить результаты, а затем повторно синхронизировать (объединить), как только все результаты будут готовы, чтобы отобразить результирующую страницу.
Псевдокод:
var value_needed_to_render_page = async.parallel([array of values to iterate over], function to call in parralel on array).join()
return page_render(value_needed_to_render_page);
Я смотрел на async и FutureJS, но ничего хорошего не получилось.
Ответ №1:
Одним из решений для этого является использование promises. Q.all
ожидает, что каждая из функций в списке вернет обещание, и будет ждать, пока все обещания разрешатся. В следующем примере используется q.js,https://github.com/kriskowal/q :
Q.all([
functionToFireRequest1,
functionToFireRequest2,
// (...)
functionToFireRequestN
]).then( function() {
doStuff();
});
Q.all
получает список функций, поэтому вы также можете сгенерировать список программно.
В качестве примера, «functionToFireRequest» будет выглядеть примерно так:
function functionToFireRequest1() {
var deferer = Q.defer();
doMyRequestABCFoo( function() { deferer.resolve() } );
// callback should be called inside your request after it finishes
return deferer.promise;
}
Комментарии:
1. Возвращает ли then() массив, состоящий из результатов всех вызовов? Или мне нужно использовать что-то вроде промежуточного программного обеспечения express-promise, чтобы иметь возможность выполнять рендеринг? Смогу ли я отображать обещания только в некоторых обработчиках?
2. (По порядку) Да, нет, Да
3. Итак, значения, которые мне нужны, должны быть переданы в качестве параметра deferer.resolve? Как в: doMyRequestABCFoo( функция() { MyCalculation; deferer.resolve(needed_value) } );
4. Похоже, что затем результат передается параметру обратного вызова вместо того, чтобы возвращать результат. Звучит ли это верно? Также .then(function(x){return x;}); не возвращает результат вычисления.
5. что вы используете для рендеринга страницы? Если вы используете express, вы можете передать res.render в
then( function(results) { res.render( results);