2015-04-28 7 views
6

Ich versuche, ein Versprechen-Wrapper-Generator zu schaffen, damit ich tun kann:Ist es möglich, Versprechen innerhalb Generator zu verpacken?

var asyncResult = PromiseWrapper($.ajax(...)); 

Bisher habe ich versucht, mit:

function PromiseWrapper(promise){ 
    return function *wrapper(promise){ 
     promise.then(function(result){ 
      yield result; 
     }, function(err){ 
      throw err; 
     }); 
    }(promise).next().value 
} 

aber dies nicht gelingt, weil innerhalb nachgebend Ein normales ist nicht erlaubt. Gibt es dafür einen Workaround? Danke: D

ps: Ich verwende babel den Code aus es6 zu übersetzen

+0

'innen Versprechen Nachgeben ist allowed' nicht - Es sollte' haben in einer normalen Funktion Nachgeben nicht – thefourtheye

+0

@thefourtheye yep ist allowed' die correct-- ist ich es jetzt –

Antwort

5

Es ist absolut unmöglich, ein Versprechen in einen Generator zu packen, der synchron das Ergebnis des Versprechens liefert, weil Versprechen immer asynchron sind. Es gibt keine Workaround dafür, es sei denn, Sie werfen mächtigere Waffen wie Fasern bei der Asynchronität.

+0

Also, wenn ich Versprechungen verwende, dann wird die Ausführung in zwei geteilt, wobei einer die Ausführung des ursprünglichen Codes ausführt und der andere die Ausführung des Versprechens ausführt? Und das Ergeben von der Ausführung des Versprechens wird nichts tun, weil der Generator erwartet, dass die Ausbeute von der ursprünglichen Codeausführung kommt? –

+1

Ja, Generatoren erwarten die 'Ausbeute' in dem aufgerufenen (wiederaufgenommenen) Code, der synchron von der 'next()' Methode "zurückkehrt". Ein Versprechen wird normalerweise erstellt, wenn eine Hintergrundaufgabe ("asynchron") gestartet wird, die einen * Rückruf * erhält, um später wieder zu kommen, wenn sie beendet ist. – Bergi

3

würde dieser Ansatz für Sie arbeiten ES5 http://davidwalsh.name/async-generators?

Ein Beispiel aus dem Link geändert:

function wrap(promise) { 
    promise.then(function(result){ 
     it.next(result); 
    }, function(err){ 
     throw err; 
    }); 
} 

function *main() { 
    var result1 = yield wrap($.ajax(...)); 
    var data = JSON.parse(result1); 
} 

var it = main(); 
it.next(); // get it all started 

Sie sollten wahrscheinlich die Gesamtheit dieser Beitrag gelesen, die runGenerator ist ein recht ordentlich Ansatz.

+0

bearbeiten werde Es ist ein großer Artikel [Bessere Asynchrones JavaScript] (http://eng.localytics.com/better-asynchronous-javascript/), in dem erläutert wird, wie Versprechen abgegeben werden können. – jaydoubleyou

0
function step1(){ 

    return new Promise(function(c,e){ 
     setTimeout(function(){ 
       c(`1000 spet 1`); 
     },1000) 
    }) 

} 

function step2(){ 
    return new Promise(function(c,e){ 
     setTimeout(function(){ 
      c(`100 spet 2`); 
     },10000) 
    }) 
} 


function step3(){ 
    return new Promise(function(c,e){ 
     setTimeout(function(){ 
      c(`3000 spet 3`); 
     },3000) 
    }) 
} 


function step4(){ 
    return new Promise(function(c,e){ 
     setTimeout(function(){ 
      c(`100 spet 4`); 
     },100) 
    }) 
} 



function *main() { 
    var ret = yield step1(); 
    try { 
     ret = yield step2(ret); 
    } 
    catch (err) { 
     ret = yield step2Failed(err); 
    } 
    ret = yield Promise.all([ 
     step3(ret) 

    ]); 

    yield step4(ret); 
} 

var it = main(); 

/* 
while (true) { 
    var current = it.next(); 
    if (current.done) break; 
    console.log(current.value); 
} 
*/ 
Promise.all([ ...it ]) // Convert iterator to an array or yielded promises. 
    .then(
     function handleResolve(lines) { 

      for (var line of lines) { 
       console.log(line); 
      } 
     }) 
Verwandte Themen