Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Promise 构造函数内部的异常为何没有阻止后续代码执行?_创想鸟

Promise 构造函数内部的异常为何没有阻止后续代码执行?

promise 构造函数内部的异常为何没有阻止后续代码执行?

Promise 构造函数内部的同步执行器(executor)中抛出的异常并不会立即中断整个脚本的执行。这是因为 Promise 内部机制会捕获这些异常,并将 Promise 的状态设置为 rejected,但不会阻止后续代码的执行。理解 Promise 的这种行为对于编写健壮的异步代码至关重要。

当我们在使用 new Promise() 创建 Promise 对象时,会传入一个执行器函数(executor)。这个执行器函数会被立即同步执行。如果在执行器函数内部发生了错误,例如调用了一个未定义的函数,我们可能会期望脚本立即停止执行。然而,实际情况并非如此。

Promise 内部的异常捕获机制

Promise 的设计初衷是为了更好地处理异步操作。为了保证异步操作的可靠性,Promise 内部实现了一个异常捕获机制。当执行器函数抛出异常时,Promise 会捕获这个异常,并将 Promise 的状态设置为 rejected。

具体来说,ECMAScript 规范中对 Promise 构造函数有如下定义:

Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).If completion is an abrupt completion, thena. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).Return promise.

第 10 步表明,如果执行器函数 (executor) 发生异常(abrupt completion),Promise 会调用 reject 函数,但不会阻止后续代码的执行,而是继续执行第 11 步,返回 Promise 对象。

示例代码与解释

考虑以下代码:

console.log('first');const promise1 = new Promise((resolve, reject) => {  console.log('inside executor');  let what = 1;  console.log(what()); // 抛出 TypeError  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 ()

可以看到,尽管 console.log(what()); 抛出了 TypeError,但 console.log(‘continues’); 仍然被执行了。这是因为 Promise 内部捕获了 TypeError,并将 promise1 的状态设置为 rejected,但没有阻止后续代码的执行。

模拟 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(); // 通知所有 then/catch 回调  }  #resolve(value) {    if (this.#state !== "pending") return;    this.#state = "fulfilled";    this.#resolvedValue = value;    this.#broadcast();  }  then(onFulfilled, onRejected) {    return new MyPromise((resolve, reject) => {      this.#customers.push({        resolve: resolve,        reject: reject,        onFulfilled: onFulfilled,        onRejected: onRejected,      });      if (this.#state === "fulfilled") {        this.#broadcast();      } else if (this.#state === "rejected") {        this.#broadcast();      }    });  }  catch(onRejected) {    return this.then(null, onRejected);  }  #broadcast() {    if (this.#state === "fulfilled") {      this.#customers.forEach((customer) => {        if (customer.onFulfilled) {          try {            const result = customer.onFulfilled(this.#resolvedValue);            customer.resolve(result);          } catch (err) {            customer.reject(err);          }        } else {          customer.resolve(this.#resolvedValue);        }      });    } else if (this.#state === "rejected") {      this.#customers.forEach((customer) => {        if (customer.onRejected) {          try {            const result = customer.onRejected(this.#resolvedValue);            customer.resolve(result);          } catch (err) {            customer.reject(err);          }        } else {          customer.reject(this.#resolvedValue);        }      });    }  }}// 使用示例console.log("start");const myPromise = new MyPromise((resolve, reject) => {  console.log("inside executor");  try {    let what = 1;    console.log(what());    resolve("Success");  } catch (error) {    reject(error);  }});myPromise  .then((result) => {    console.log("then:", result);  })  .catch((error) => {    console.error("catch:", error);  });console.log("end");

在 MyPromise 类的构造函数中,try…catch 块捕获了执行器函数中可能抛出的异常,并通过 #reject 方法将 Promise 的状态设置为 rejected。

如何处理 Promise 中的异常

虽然 Promise 内部会捕获异常,但我们仍然需要显式地处理这些异常,以避免程序出现未知的错误。通常,我们可以使用 catch() 方法或 async/await 结合 try…catch 块来处理 Promise 中的异常。

使用 catch() 方法:

promise1  .then((result) => {    console.log('Result:', result);  })  .catch((error) => {    console.error('Error:', error);  });

使用 async/await 结合 try…catch 块:

async function myFunction() {  try {    const result = await promise1;    console.log('Result:', result);  } catch (error) {    console.error('Error:', error);  }}

总结

Promise 构造函数内部的异常不会立即中断整个脚本的执行,而是会被 Promise 内部机制捕获,并将 Promise 的状态设置为 rejected。为了保证程序的健壮性,我们需要显式地处理 Promise 中的异常,可以使用 catch() 方法或 async/await 结合 try…catch 块。理解 Promise 的这种行为对于编写可靠的异步代码至关重要。

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

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

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
js中caller是什么意思
上一篇 2025年12月21日 01:57:22
使用 PHP 和 AJAX/JSON 将数据传递到 JavaScript 的教程
下一篇 2025年12月21日 01:57:35

相关推荐

发表回复

登录后才能评论
关注微信