2017-03-13 3 views
1

Angenommen, ich habe einen Koa Webserver mit einem Endpunkt wie folgt aus:Wie Generatorfunktionen parallel ausgeführt werden?

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

Nun wird der Kunde die erhalten reagieren, nachdem alle Aktionen offensichtlich durchgeführt werden. aber die Dinge sind jede Handlung hängt von der Vollendung der vorherigen ab.

Gibt es eine Möglichkeit, sie parallel auszuführen?

Hinweis: Sie zu Promises zu schalten ist keine Option, es sei denn, ich kann die Ergebnisse irgendwie zurückgeben und sie nicht auflösen().

Antwort

1

co schalten die Generatorfunktion zu Promises, und führt sie async. Promise.all wartet auf alle von ihnen zu beenden:

exports.getResults = function*() { 

    var actions = [...]; 

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

Wenn die Generatoren als Koroutinen verwendet werden, durch die async/await Strömung simulieren, dann sollten Sie in der Lage zu tun:

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

oder sogar:

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

Ich bin nicht sicher über die genaue Verwendung hier, aber wenn Sie Generatoren mit co oder Bluebird.coroutine dann verwenden Sie bereits Versprechungen, so können Sie sie auch expliziter verwenden.

Anstatt also:

exports.getResults = function*() { 

    var actions = [...]; 
    var results = []; 

    for (var action of actions) { 

     var result = yield perform(action); 

     results.push(results); 
    } 

    return results; 
} 

können Sie versuchen:

exports.getResults = function*() { 

    var actions = [...]; 

    return yield Promise.all(actions.map(perform)); 
} 
+0

Problem ist 'ausführen (Aktion)' kehrt suspendierte Generator und wird ausgeführt, nicht die eigentliche 'ausführen()'. Wenn es dann zurückkommt, führt Koa (oder Bluebird.coroutine, glaube ich) die Funktion tatsächlich aus. –

+0

Um die Funktion ausführen zu können, kann ich 'co' lib verwenden, macht diese Lösung Sinn? 'return Ausbeute Promise.all (actions.map (function (action) { \t \t return Co (Funktion *() { \t \t \t return Ausbeute durchzuführen (action); \t \t } \t})); ' –

+0

@ ShaiBen-Dor Ja, es macht Sinn,' co' ist sehr gut für solche Sachen.Man kann auch 'co.wrap' (Teil des' co' Moduls) und Coroutine von Bluebird - see benutzen http://bluebirdjs.com/docs/api/promise.coroutine.html – rsp

Verwandte Themen