J'ai découvert les promesses javascript récemment. Un avantage annoncé est l'imbrication propre en enchaînant les clauses.achèvement d'une promesse, avant de commencer la suivante, dans une longue liste
Mon code fonctionne comme prévu, mais l'imbrication devient tout aussi moche que lorsque j'ai utilisé des rappels. Y a-t-il une meilleure façon d'utiliser le chaînage d'alors pour supprimer toute cette imbrication? Remarque J'ai besoin de terminer la tâche n avant que quoi que ce soit dans la tâche n + 1 puisse commencer.
Le simple exemple fixe
'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()
})
})
D'après les commentaires que je l'aurais fait
P1().then(() => {
return P2()
}).then(() => {
return P3()
}).catch(() => { console.log("yikes something failed")})
Le code réel reçoit un tableau de choses à traiter de manière séquentielle. Le format suggéré ci-dessus ne convient que lorsque la séquence d'étapes est spécifiée en tant que code. On dirait qu'il devrait y avoir une sorte de Promise.do_these_sequentialy, plutôt que mon code construisant explicitement la chaîne de promesses. Comme suit:
'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")
})