异步等待中的多个 Promise

问题描述 投票:0回答:1

我面临着困惑,希望得到一些澄清或参考文章来解释以下代码片段中观察到的行为。

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise Resolved Value!!");
  }, 20000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise Resolved Value!!");
  }, 10000);
});


async function handlePromise() {
  try {
    console.log("Hello World!!");
    const val = await p1;
    console.log("Namaste JavaScript");
    console.log(val);

    const val2 = await p2;
    console.log("Namaste JavaScript 2");
    console.log(val2);
  } catch (error) {
    console.error("Error:", error);
  }
}
handlePromise();

在这种情况下,程序会打印“Hello World!!”然后等待20秒。等待期结束后,p1 和 p2 部分将同时打印。我试图理解为什么两个承诺同时执行。

但是

对于这段代码

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise Resolved Value!!");
  }, 10000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise Resolved Value!!");
  }, 20000);
});


async function handlePromise() {
  try {
    console.log("Hello World!!");
    const val = await p1;
    console.log("Namaste JavaScript");
    console.log(val);

    const val2 = await p2;
    console.log("Namaste JavaScript 2");
    console.log(val2);
  } catch (error) {
    console.error("Error:", error);
  }


}

handlePromise();

在这种情况下,打印“Hello World!!”后,程序在延迟 20 秒后打印 p1 部分,然后在延迟 10 秒后打印 p2 部分。我正在寻求对这种特定计时行为的解释。

任何解释 JavaScript Promise 底层异步性质的文章的见解或参考都会非常有帮助。谢谢!

试图寻求对多重承诺、异步等待行为的解释

javascript async-await promise
1个回答
0
投票

请务必记住,

await
不会阻止 javascript 解释器。当您等待时,其他事情仍然可能发生,并且其他代码片段仍然可以在您等待的事件完成之前执行。
await
关键字只会阻止您的功能。

首先,两种情况是相同的:计划在 10 秒后完成的任务始终在 10 秒后完成,计划在 20 秒后完成的任务始终在 20 秒后完成。总是。这两项任务都不需要 30 秒才能完成,因为您已同时启动这两项任务。

为了证明这是真的,让我们在测试代码中删除

await

function handlePromise() {
    p1.then((val) => {
        console.log("Namaste JavaScript");
        console.log(val);
    }).catch((error) =>  {
        console.error("Error:", error);
    })

    p2.then((val2) => {
        console.log("Namaste JavaScript 2");
        console.log(val2);
    }).catch((error) =>  {
        console.error("Error:", error);
    })
}
handlePromise();

您将在场景 1 中看到 p2 首先完成,然后 p1 在 10 秒后完成,而在场景 2 中则发生相反的情况。两个计时器并行运行。

在您的代码中,您基本上是这样做的:

function handlePromise() {
    p1.then((val) => {
        console.log("Namaste JavaScript");
        console.log(val);
        return p2;
    }).then((val2) => {
        console.log("Namaste JavaScript 2");
        console.log(val2);
    }).catch((error) =>  {
        console.error("Error:", error);
    })
}
handlePromise();

因此,在场景 1 中,p2 在 p1 之前完成,但在 p1 完成之前我们不会处理 p2 的结果。因此,当 p1 完成时,p2 的结果也会立即处理,因为它是 10 秒前完成的。

要获得我认为您期望的结果,请不要在想要启动之前启动

setTimeout

function startP1 () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Promise Resolved Value!!");
    }, 20000);
  });
}

function startP2 () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Promise Resolved Value!!");
    }, 10000);
  });
}


async function handlePromise() {
  try {
    console.log("Hello World!!");
    const val = await startP1();
    console.log("Namaste JavaScript");
    console.log(val);

    const val2 = await startP2();
    console.log("Namaste JavaScript 2");
    console.log(val2);
  } catch (error) {
    console.error("Error:", error);
  }
}
handlePromise();

PS:

另外要记住的是,Promise 构造函数的回调是同步执行的,而不是异步的。我们可以通过运行以下代码看到情况是这样的:

console.log('hello');
new Promise((ok,fail) => {
  console.log('cruel');
});
console.log('world');

上面的代码打印:

hello
cruel
world

不是

hello, world, cruel
。您传递给 Promise 构造函数的函数是同步执行的。

© www.soinside.com 2019 - 2024. All rights reserved.