在开始下一个承诺之前,在一个长长的列表中完成一个承诺
completion of one promise, before starting the next, in a long list
我最近发现了 javascript 承诺。一个宣传的好处是通过链接 then 子句来干净嵌套。
我的代码按预期工作,但嵌套增长与我使用回调时一样难看。有没有更好的方法来使用 then 的链接来删除所有这些嵌套?请注意,我需要先完成任务 n,然后才能开始任务 n+1 中的任何内容。
非常简单的固定示例
'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" )})
真正的代码接收一组要顺序处理的东西。
仅当步骤序列指定为代码时,上面建议的格式才合适。似乎应该有某种 Promise.do_these_sequentialy,而不是我的代码显式构建承诺链。如下:
'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")
})
你误解了 Promise 的工作原理。您可以链接 return 值以及 Promise 实例,并沿着链进一步传递它们:
P1()
.then(() => P2())
.then(() => P3())
无需嵌套。
P1()
.then(() => P2())
.then(() => P3())
你可以让你的代码更扁平化。
还有explicit construction is an antipattern
看看async/await,大大简化了 promise 的编写。
JavaScript’s Async/Await Blows Promises Away
基本上,它包括编写异步函数,如同步代码:
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()
我个人喜欢这种格式的外观和我使用的格式
foo(){
P1().then(()=>{
return P2();
}).then(()=>{
return P3();
}).catch((err)=>{
//handle errors
});
}
我最近发现了 javascript 承诺。一个宣传的好处是通过链接 then 子句来干净嵌套。
我的代码按预期工作,但嵌套增长与我使用回调时一样难看。有没有更好的方法来使用 then 的链接来删除所有这些嵌套?请注意,我需要先完成任务 n,然后才能开始任务 n+1 中的任何内容。
非常简单的固定示例
'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" )})
真正的代码接收一组要顺序处理的东西。 仅当步骤序列指定为代码时,上面建议的格式才合适。似乎应该有某种 Promise.do_these_sequentialy,而不是我的代码显式构建承诺链。如下:
'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")
})
你误解了 Promise 的工作原理。您可以链接 return 值以及 Promise 实例,并沿着链进一步传递它们:
P1()
.then(() => P2())
.then(() => P3())
无需嵌套。
P1()
.then(() => P2())
.then(() => P3())
你可以让你的代码更扁平化。 还有explicit construction is an antipattern
看看async/await,大大简化了 promise 的编写。
JavaScript’s Async/Await Blows Promises Away
基本上,它包括编写异步函数,如同步代码:
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()
我个人喜欢这种格式的外观和我使用的格式
foo(){
P1().then(()=>{
return P2();
}).then(()=>{
return P3();
}).catch((err)=>{
//handle errors
});
}