簡體   English   中英

Node.js Promise 鏈解析過早

[英]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();

sleepsleep串行操作拆分為自己的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM