[英]Node.js Promise chain resolving too early
有一些關於鏈接承諾的事情我不明白。 下面的 Node.js 片段生成以下 output。 為什么promise.allSettled
在第 18 行的第一次sleep
后調用,而不是在第 21 行的第二次睡眠后調用?
Cycle 0 is going to sleep promise.js:2
Cycle 0 slept for 2 seconds promise.js:6
Returned from sleep function promise.js:19
Cycle 0 is going to sleep promise.js:2
Done with the process promise.js:27
Cycle 0 slept for 2 seconds promise.js:6
function sleep(cycle) { console.log(`Cycle ${ cycle } is going to sleep`); return new Promise(resolve => { setTimeout(() => { console.log(`Cycle ${ cycle } slept for 2 seconds`); resolve(); }, 2000); }); } function process() { let cycles = 1; let subprocesses = []; for (let i = 0; i < cycles; i++) { subprocesses.push( sleep(i).then(() => { console.log('Returned from sleep function'); sleep(i); }) ); } Promise.allSettled(subprocesses).then(results => { console.log('Done with the process'); }); } process();
因為您還沒有解決 promise 創建的sleep(i).then
.then 到 promise 從第二次sleep
,所以它不會等待第二次操作完成后再穩定。 您需要在第二次調用之前return
:
function sleep(cycle) { console.log(`Cycle ${ cycle } is going to sleep`); return new Promise(resolve => { setTimeout(() => { console.log(`Cycle ${ cycle } slept for 2 seconds`); resolve(); }, 2000); }); } function process() { let cycles = 1; let subprocesses = []; for (let i = 0; i < cycles; i++) { subprocesses.push( sleep(i).then(() => { console.log('Returned from sleep function'); return sleep(i); // <============================ }) ); } Promise.allSettled(subprocesses).then(results => { console.log('Done with the process'); }); } process();
這是一個有兩個周期的版本,並且更清楚地標記了睡眠調用:
function sleep(cycle, sub) { console.log(`Cycle ${cycle}(${sub}) is going to sleep`); return new Promise(resolve => { setTimeout(() => { console.log(`Cycle ${cycle}(${sub}) slept for 2 seconds`); resolve(); }, 2000); }); } function process() { let cycles = 2; let subprocesses = []; for (let i = 0; i < cycles; i++) { subprocesses.push( sleep(i, "a").then(() => { console.log(`Returned from sleep function (${i})`); return sleep(i, "b"); // <============================ }) ); } Promise.allSettled(subprocesses).then(results => { console.log('Done with the process'); }); } process();
將sleep
、 sleep
串行操作拆分為自己的 function 可能更清楚,也許是async
function:
async function twoSleep(i) {
await sleep(i, "a");
console.log(`Returned from sleep function (${i})`);
await sleep(i, "b");
}
function process() {
let cycles = 2;
let subprocesses = [];
for (let i = 0; i < cycles; i++) {
subprocesses.push(twoSleep(i));
}
Promise.allSettled(subprocesses).then(results => {
console.log('Done with the process');
});
}
function sleep(cycle, sub) { console.log(`Cycle ${cycle}(${sub}) is going to sleep`); return new Promise(resolve => { setTimeout(() => { console.log(`Cycle ${cycle}(${sub}) slept for 2 seconds`); resolve(); }, 2000); }); } async function twoSleep(i) { await sleep(i, "a"); console.log(`Returned from sleep function (${i})`); await sleep(i, "b"); } function process() { let cycles = 2; let subprocesses = []; for (let i = 0; i < cycles; i++) { subprocesses.push(twoSleep(i)); } Promise.allSettled(subprocesses).then(results => { console.log('Done with the process'); }); } process();
問題是 Promise.allSettled 並行運行所有承諾,因此所有承諾同時解決。 如果你想一一運行它們
async function process() {
const cycles = 1;
for (let i = 0; i < cycles; i++) {
await sleep(i).then(() => {
console.log("Returned from sleep function");
return sleep(i);
});
}
console.log("Done with the process");
}
process();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.