我正面临一个困惑,希望能有一些澄清或参考文章来解释在以下代码片段中观察到的行为.

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部分同时打印.我在试着理解为什么两个promise 都要同时执行.

对于这段代码

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部分.我正在为这一特定的时机行为寻求解释.

任何关于解释JavaScriptpromise 的底层异步性质的文章的见解或参考都将非常有帮助.谢谢!

试图寻求对多重promise 行为的解释,异步等待

推荐答案

重要的是要记住,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构造函数的函数将同步执行.

Javascript相关问答推荐

订阅操作顺序

TestCafe预计文本等于以下内容之一

Fastify错误:CORS策略已阻止从起源api-dev.example.com上的MLhttp请求

如何使用JavaScript动态地将CSS应用于ToDo列表?

React Native平面列表自动滚动

是什么原因导致此Angular 16电影应用程序中因类型错误而不存在属性?

传递一个大对象以在Express布局中呈现

点击按钮一次有文本出现和褪色,而不是点击两次?(html,CSS,JavaScript)

如何将Map字符串,布尔值转换为{key:string;value:bo布尔值;}[]?<>

在服务器上放置了Create Reaction App Build之后的空白页面

如何将Openjphjs与next.js一起使用?

PDF工具包阿拉伯字体的反转数字

如何通过将实例方法的名称传递给具有正确类型的参数的继承方法来调用实例方法?

您能在卸载程序(QtInsteller框架)上添加WizardPage吗?

更改预请求脚本中重用的JSON主体变量- Postman

在HTML语言中调用外部JavaScript文件中的函数

是否可以在Photoshop CC中zoom 路径项?

Google脚本数组映射函数横向输出

是否可以将Select()和Sample()与Mongoose结合使用?

是否可以将异步调用与useState(UnctionName)一起使用