Как выполнять функции генератора в параллельном режиме?

Предполагая, что у меня есть веб-сервер 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));
}