2015-04-28 20 views
6

Próbuję utworzyć obietnica owijkę przy użyciu generatora tak, że mogę zrobić:Czy można owinąć obietnicę wewnątrz generatora?

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

Do tej pory starałem się:

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

ale to się nie powiedzie, ponieważ uzyskując wewnątrz normalne nie jest dozwolone. Czy jest do tego jakieś obejście? Dziękuję: D

PS: Używam babel tłumaczyć kod z ES6 do ES5

+0

'plonowanie wewnątrz obietnicy nie jest allowed' - To powinno być' plonowanie wewnątrz prawidłową czynnością nie jest allowed' – thefourtheye

+0

@thefourtheye Yep, który jest correct-- będę go zmieniać teraz –

Odpowiedz

5

Obietnica jest całkowicie niemożliwa do złożenia w generatorze, który synchronicznie przynosi rezultat obietnicy, ponieważ obietnice są zawsze asynchroniczne. Nie ma na to żadnego rozwiązania, chyba że wyrzucisz potężniejsze bronie, takie jak włókna w asynchronii.

+0

, więc jeśli użyję obietnic, to wykonanie zostanie podzielone na 2, przy czym jeden będzie realizowany przy użyciu oryginalnego kodu, a drugi będzie realizowany zgodnie z obietnicą? A ustępowanie od wykonania obietnicy nic nie da, ponieważ generator oczekuje, że zysk zacznie pochodzić z pierwotnego wykonania kodu? –

+1

Tak, generatory oczekują 'yield' w wywołanym (wznowionym) kodzie, który" zwraca "synchronicznie z metody' next() '. Zazwyczaj obietnica jest tworzona, gdy uruchamiane jest pewne zadanie w tle ("asynchroniczne"), które otrzymuje * wywołanie zwrotne *, aby powrócić później po zakończeniu. – Bergi

3

będzie to praca dla ciebie http://davidwalsh.name/async-generators podejście?

przykładem modyfikowany link:

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 

należy prawdopodobnie przeczytać całość tego stanowiska, runGenerator jest całkiem miłe podejście.

+0

Jest doskonałym artykule [Better Asynchroniczny JavaScript] (http://eng.localytics.com/better-asynchronous-javascript/) wyjaśniający, w jaki sposób przynosić obietnice. – 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); 
      } 
     })