Как запустить функции генератора параллельно?

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

Теперь клиент получит ответ после того, как ВСЕ действия будут выполнены явно. но дело в том, что каждое действие зависит от завершения предыдущего.

Есть ли способ выполнить их параллельно?

Примечание. Превратить их в Обещания нельзя, если только я не смогу как-то вернуть результаты, а не разрешить () их.

3 ответа

Решение

co превращает функцию генератора в Promises и выполняет их асинхронно. Promise.all ждет, пока все они закончат

exports.getResults = function* () {

    var actions = [...];

    return yield Promise.all(actions.map(function(action) { 
        return co(function*() { 
            return yield perform(action); 
        } 
    }));
}

Если генераторы используются в качестве сопрограмм, имитируя async/await поток, то вы должны быть в состоянии сделать:

var results = yield Promise.all(actions.map(action => perform(action)));

или даже:

var results = yield Promise.all(actions.map(perform));

Я не уверен насчет точного использования здесь, но когда вы используете генераторы с co или же Bluebird.coroutine тогда вы уже используете обещания, так что вы можете использовать их более явно.

Итак, вместо:

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));
}

если вы используете Redux Saga, перейдите по этой ссылке

https://redux-saga.js.org/docs/advanced/RunningTasksInParallel/

Другие вопросы по тегам