2015-08-27 33 views
1

相當新的ES6和好奇,想知道一個全產業鏈的完成目前是否有承諾,我可以future.wait()如何等待承諾的在Javascript ECMAScript2015(ES6)

我有一個名爲​​方法做了,這啓動了一系列的承諾。我有這個方法的兩個要求:

  • 每一個承諾,當最後一個願望已經完成了應該只啓動(這部分我已經實現)
  • ​​時承諾的整個鏈條已經執行完畢應僅返回(即我想阻止,直到最後的承諾是完整的)

這裏是我的示例代碼:

/* Require dependencies */ 
require('babel/polyfill'); 

class PromiseWaiter { 
    /* Constructor */ 
    constructor() { 
    } 

    /* Methods */ 
    execute() { 
    let _this = this; 

    runPromiseGenerator(function *promiseGenerator() { 
     yield _this.asyncMethod1(); 
     yield _this.asyncMethod2(); 
     yield _this.asyncMethod3(); 
    }); 

    return true; 
    } 

    asyncMethod1() { 
    return returnDummyPromise('method 1', 800); 
    } 
    asyncMethod2() { 
    return returnDummyPromise('method 2', 200); 
    } 
    asyncMethod3() { 
    return returnDummyPromise('method 3', 200); 
    } 
} 

var runPromiseGenerator = function(generator) { 
    var it = generator(), ret; 

    // asynchronously iterate over generator 
    (function iterate(val) { 
    ret = it.next(val); 

    if (!ret.done) { 
     // poor man's "is it a promise?" test 
     if ("then" in ret.value) { 
     // wait on the promise 
     ret.value.then(iterate); 
     } 
     // immediate value: just send right back in 
     else { 
     // avoid synchronous recursion 
     setTimeout(function(){ 
      iterate(ret.value); 
     }, 0); 
     } 
    } 
    })(); 

}; 

var returnDummyPromise = function(methodName, timeout) { 
    console.log('starting %s', methodName); 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     console.log('finished %s', methodName); 
     resolve(); 
    }, timeout); 
    }) 
}; 

module.exports = PromiseWaiter; 

這裏是我的在節點控制檯上運行測試&電流輸出:

> p = new PromiseWaiter() 
{} 
> p.execute() 
starting method 1 
true 
> finished method 1 
starting method 2 
finished method 2 
starting method 3 
finished method 3 

我想看到的是:

> p = new PromiseWaiter() 
{} 
> p.execute() 
starting method 1 
finished method 1 
starting method 2 
finished method 2 
starting method 3 
finished method 3 
true 
> 

在過去,這使用

fut = new Future(); 
// set off chain passing future 
future.wait(); 

誠徵我會做去挑選那裏最好最聰明的大腦。

在此先感謝您的時間! Elliott

+1

爲什麼要重新實現'runPromiseGenerator'? ['co'](https://www.npmjs.com/package/co)已經做到了,它用代碼處理你正在做的事情。你需要'runPromiseGenerator'來返回一個promise,所以你可以做'runPromiseGenerator(...)。然後(function(){console.log('all done');});' – loganfsmyth

+0

什麼是'future.wait ()'東西?纖維?你使用某個特定的圖書館嗎? – Bergi

回答

1

您將需要返回一個承諾,當發電機完成時將解決。我真的建議使用現有的實現像co但是如果你想擴大自己的實現:

var runPromiseGenerator = function(generator) { 
    return new Promise(function(resolve, reject){ 
    var it = generator(), ret; 

    // asynchronously iterate over generator 
    (function iterate(val) { 
     try { 
     ret = it.next(val); 

     if (!ret.done) { 
      Promise.resolve(ret.value).then(iterate, reject); 
     } 
     else { 
      resolve(ret.value); 
     } 
     } 
     catch (e){ 
     reject(e); 
     } 
    })(); 
    }); 
}; 

那麼你就可以改變你的execute

execute() { 
    let _this = this; 

    return runPromiseGenerator(function *promiseGenerator() { 
    yield _this.asyncMethod1(); 
    yield _this.asyncMethod2(); 
    yield _this.asyncMethod3(); 
    }); 
} 

,做

p.execute().then(function(){ 
    // done 
}); 

或者,您可以使用您現有的功能來調用它,例如

runPromiseGenerator(function *promiseGenerator() { 
    yield p.execute(); 

    // do something after execution 
}); 
+0

感謝你指導我合作 - 正如我所說的,我對es6很陌生,並沒有見過這個圖書館。我瞭解你的建議,回覆一個承諾,但那不是我想要的。我正在尋找一種方法來阻止執行完成,直到承諾鏈完成。我想我是從es7 –

+0

的'await'關鍵字沒問題,希望這一切都有道理。 – loganfsmyth

+1

在JS中無法阻止執行,但可以使用'yield'或'await'等語法暫停執行。如果你想在'execute'後面執行某些東西,那麼你必須使用'runPromiseGenerator'或'co'就像你已經做的那樣。我給答案增加了一個例子。ES7提出的'async/await'基本上就是你已經在這裏用生成器實現的東西,除了一個不需要外部庫的新語法。 – loganfsmyth