Promise 构造函数中的异常为何不会阻止后续脚本执行?

promise 构造函数中的异常为何不会阻止后续脚本执行?

Promise 构造函数内部的同步执行器(executor)中抛出的异常会被 Promise 机制捕获并处理,将 Promise 的状态设置为 rejected,但不会立即中断后续脚本的执行。这是因为 Promise 内部已经对异常进行了处理,避免了程序崩溃,允许后续代码继续运行。本文将深入探讨这一机制,并提供示例代码进行说明。

在学习 Promise 构造函数时,可能会遇到一个看似违反直觉的现象:在 new Promise() 内部的执行器函数中抛出异常,程序并没有立即停止,而是继续执行了后续的代码。

例如以下代码:

console.log('first');const promise1 = new Promise((resolve, reject) => {  console.log('inside executor');  let what = 1  console.log(what());  console.log('not reached');  resolve('Hi Guys!');});console.log('continues'); // 为什么会继续执行?

这段代码的输出结果是:

firstinside executorcontinuesUncaught (in promise) TypeError: what is not a function  at index.js:5:15  at new Promise ()

可以看到,尽管 what() 导致了 TypeError 异常,但 console.log(‘continues’) 仍然被执行了。 这背后的原因在于 Promise 内部对异常的处理机制。

Promise 的异常处理机制

Promise 构造函数接收一个执行器函数(executor)作为参数。 这个执行器函数会立即同步执行。如果执行器函数内部抛出了异常,Promise 内部会捕获这个异常,并将 Promise 的状态设置为 rejected。 重要的是,这个捕获和状态变更是在 Promise 内部完成的,不会直接中断外部代码的执行。

根据 ECMAScript 规范,Promise 构造函数的具体步骤如下:

创建一个新的 Promise 对象。调用执行器函数,并传入 resolve 和 reject 两个函数作为参数。如果执行器函数执行过程中抛出了异常,则调用 reject 函数,并将异常作为参数传递给它。返回新创建的 Promise 对象。

关键在于,即使执行器函数抛出了异常,Promise 构造函数仍然会正常返回 Promise 对象,而不会立即中断后续代码的执行。

模拟 Promise 内部实现

为了更好地理解 Promise 的异常处理机制,我们可以简单地模拟 Promise 构造函数的内部实现:

class MyPromise {    #state    #resolvedValue    #customers    constructor(executor) {        this.#state = "pending";        this.#customers = [];        try {             executor((value) => this.#resolve(value),                       (reason) => this.#reject(reason));        } catch(err) {             this.#reject(err);         }    }    #reject(reason) {        if (this.#state !== "pending") return;        this.#state = "rejected";        this.#resolvedValue = reason;        this.#broadcast();    }}

在这个模拟实现中,try…catch 块捕获了执行器函数中可能抛出的异常,并调用 #reject 方法将 Promise 的状态设置为 rejected。 即使发生了异常,constructor 函数仍然会正常返回。

如何处理 Promise 的 rejected 状态

虽然 Promise 内部捕获了异常,但我们仍然需要处理 Promise 的 rejected 状态。 通常使用 .catch() 方法或者 async/await 结构中的 try…catch 块来处理。

例如:

console.log('first');const promise1 = new Promise((resolve, reject) => {  console.log('inside executor');  let what = 1  console.log(what());  console.log('not reached');  resolve('Hi Guys!');}).catch(error => {  console.error("Promise rejected:", error);});console.log('continues');

或者使用 async/await:

async function myFunction() {  console.log('first');  try {    const result = await new Promise((resolve, reject) => {      console.log('inside executor');      let what = 1      console.log(what());      console.log('not reached');      resolve('Hi Guys!');    });    console.log("Promise resolved:", result);  } catch (error) {    console.error("Promise rejected:", error);  }  console.log('continues');}myFunction();

总结

Promise 构造函数内部的执行器函数中抛出的异常不会立即中断后续脚本的执行,这是因为 Promise 内部对异常进行了捕获和处理。为了处理 Promise 的 rejected 状态,我们需要使用 .catch() 方法或者 async/await 结构中的 try…catch 块。 这种机制使得 Promise 能够更好地处理异步操作中的异常,避免程序崩溃。

以上就是Promise 构造函数中的异常为何不会阻止后续脚本执行?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1534877.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
JavaScript 中 toSpliced() 方法报错:原因与解决方案
上一篇 2025年12月21日 01:58:00
如何将图片转换为终端像素艺术并优化其显示尺寸
下一篇 2025年12月21日 01:58:12

相关推荐

发表回复

登录后才能评论
关注微信