Как выполнять функции генератора в параллельном режиме?
Предполагая, что у меня есть веб-сервер Koa с конечной точкой, например:
const perform = require(...); // some generator function
exports.endpoint = function* () {
var results = yield getResults();
// Respond the results
this.body = results;
}
exports.getResults = function* () {
var actions = [...];
var results = [];
for (var action of actions) {
var result = yield perform(action);
results.push(results);
}
return results;
}
Теперь клиент получит ответ после того, как все действия будут выполнены явно. но каждое действие зависит от завершения предыдущего.
Есть ли способ выполнить их параллельно?
Примечание. Переключение на Promises не является параметром, если я не могу как-то вернуть результаты и не разрешить() их.
Ответы
Ответ 1
co
превращает функцию генератора в Promises и выполняет их async. Promise.all
ожидает, что все они будут завершены:
exports.getResults = function* () {
var actions = [...];
return yield Promise.all(actions.map(function(action) {
return co(function*() {
return yield perform(action);
}
}));
}
Ответ 2
Если генераторы используются как сопрограммы, имитируя поток async
/await
, то вы должны уметь:
var results = yield Promise.all(actions.map(action => perform(action)));
или даже:
var results = yield Promise.all(actions.map(perform));
Я не уверен в точном использовании здесь, но когда вы используете генераторы с co
или Bluebird.coroutine
, вы уже используете promises, поэтому вы можете использовать их более явно.
Итак, вместо:
exports.getResults = function* () {
var actions = [...];
var results = [];
for (var action of actions) {
var result = yield perform(action);
results.push(results);
}
return results;
}
вы можете попробовать:
exports.getResults = function* () {
var actions = [...];
return yield Promise.all(actions.map(perform));
}