【问题标题】:Is it possible to wrap promise inside generator?是否可以在生成器中包装承诺?
【发布时间】:2015-04-28 07:34:13
【问题描述】:

我正在尝试使用生成器创建一个承诺包装器,以便我可以这样做:

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

到目前为止,我一直在尝试:

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

但这失败了,因为不允许在法线内屈服。 有什么解决方法吗?谢谢 :D

ps:我正在使用 babel 将代码从 es6 翻译成 es5

【问题讨论】:

  • yielding inside promise is not allowed - 应该是yielding inside a normal function is not allowed
  • @thefourtheye 没错,我现在就编辑它

标签: javascript generator ecmascript-6 es6-promise


【解决方案1】:

完全不可能将 promise 包装在同步生成 promise 结果的生成器中,因为 promise 始终是异步的。没有解决办法,除非你在异步中扔出更强大的武器,比如纤维。

【讨论】:

  • 所以如果我使用promises,那么执行会被分成2个,一个沿着原始代码执行,另一个沿着promise执行?并且从 promise-execution 中产生不会做任何事情,因为生成器期望收益来自原始代码执行?
  • 是的,生成器期望调用(恢复)代码中的 yieldnext() 方法同步“返回”。 Promise 通常在启动某些后台任务(“异步”)时创建,并在完成后给定一个 callback 以便稍后返回。
【解决方案2】:

这种方法对你有用吗http://davidwalsh.name/async-generators

链接中的修改示例:

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

您可能应该阅读该帖子的全部内容,runGenerator 是一种非常简洁的方法。

【讨论】:

【解决方案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 );
            }
        })

【讨论】:

    猜你喜欢
    • 2015-07-25
    • 2020-06-22
    • 1970-01-01
    • 2018-04-23
    • 2017-07-18
    • 1970-01-01
    • 2020-03-27
    • 2016-06-22
    • 2012-06-09
    相关资源
    最近更新 更多