Is it possible to wrap promise inside generator?

2019-04-08 01:42发布

问题:

I'm trying to create a promise-wrapper using generator so that I can do:

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

So far, I've been trying with:

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

but this fails because yielding inside a normal is not allowed. Is there any work-around for this? Thank you :D

ps: I'm using babel to translate the code from es6 to es5

回答1:

It is utterly impossible to wrap a promise in a generator that synchronously yields the promise's result, because promises are always asynchronous. There is no workaround for that, unless you throw mightier weapons like fibers at the asynchrony.



回答2:

Would this approach work for you http://davidwalsh.name/async-generators ?

A modified example from the 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

You should probably read the entirety of that post, the runGenerator is a pretty neat approach.



回答3:

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