完成一个承诺,在开始下一个,在一个长长的名单

我最近发现了JavaScript的承诺。 广告的好处是干净的嵌套链接然后从句。

我的代码按预期工作,但嵌套增长就像我使用callback时一样丑陋。 有没有更好的方法来使用链接然后删除所有这些嵌套? 注意我需要在任务n + 1中的任何事情可以开始之前完成任务n。

非常简单的固定例子

'use strict'; function P1() { return new Promise((resolve) => { console.log("starting 1") setTimeout(() => { console.log("done 1") resolve(); }, 100) }) } function P2() { return new Promise((resolve) => { console.log("must start 2 only after 1 is done") setTimeout(() => { console.log("done 2") resolve(); }, 50) }) } function P3() { return new Promise((resolve) => { console.log("must start 3 only after 3 is done") setTimeout(() => { console.log("done 3") resolve(); }, 10) }) } console.log("this works, but if list was long, nesting would be terribly deep"); // start 1, done 1, start 2, done 2, start 3, done 3. P1().then(() => { P2().then(() => { P3() }) }) 

基于我应该做的反馈

 P1().then(() => { return P2() }).then(() => { return P3() }).catch(() => { console.log("yikes something failed" )}) 

真正的代码接收一连串的东西来处理。 上述build议的格式只有在步骤序列被指定为代码时才适用。 似乎应该有某种Promise.do_these_sequentialy,而不是我的代码明确构build承诺链。 如下:

 'use strict'; function driver(single_command) { console.log("executing " + single_command); // various amounts of time to complete command return new Promise((resolve) => { setTimeout(() => { console.log("completed " + single_command); resolve() }, Math.random()*1000) }) } function execute_series_of_commands_sequentialy(commands) { var P = driver(commands.shift()); if (commands.length > 0) { return P.then(() => { return execute_series_of_commands_sequentialy(commands) }) } else { return P } } execute_series_of_commands_sequentialy([1, 2, 3, 4, 5, 6, 7, 8, 9]).then(() => { console.log("test all done") }) 

 P1() .then(() => P2()) .then(() => P3()) 

你可以使你的代码更平坦。 另外明确的构造是反模式

你误会了诺言如何工作。 您可以链接返回值以及Promise实例,并沿着链进一步传递它们:

 P1() .then(() => P2()) .then(() => P3()) 

没有必要嵌套它们。

我个人喜欢这种格式看起来是什么,我使用

 foo(){ P1().then(()=>{ return P2(); }).then(()=>{ return P3(); }).catch((err)=>{ //handle errors }); } 

看看asynchronous/等待,大大简化了诺言的写作。

JavaScript的asynchronous/等待吹的承诺

基本上,它包含了写同步代码这样的asynchronous函数:

 async function P(number) { return new Promise((resolve) => { console.log("starting "+number) setTimeout(() => { console.log("done "+number) resolve(); }, 800) }) } /* Or the ES6 version : const P = async (number) => new Promise((resolve) => { ... }) */ async function run(){ await P(1) await P(2) await P(3) console.log("All done!") } run()