JavaScript 教程:深入理解 Promise 机制

JavaScript 教程:深入理解 Promise 机制

en.javascript.info Modern JavaScript Tutorial en.javascript.info 项目地址: https://gitcode.com/gh_mirrors/en/en.javascript.info

什么是 Promise?

想象你是一位知名歌手,粉丝们日夜追问你新歌的发布时间。为了应对这种情况,你承诺在新歌发布时会立即通知所有订阅的粉丝。你创建了一个订阅列表,粉丝可以填写他们的邮箱地址。这样无论歌曲何时发布,所有订阅者都能第一时间收到通知。即使录音室发生火灾导致歌曲无法发布,你也会通知粉丝这个坏消息。

这个生活场景完美类比了编程中的 Promise 机制:

  1. 生产代码:需要时间执行的操作(如网络请求获取数据),就像歌手录制歌曲
  2. 消费代码:需要生产代码结果的多个函数,就像等待新歌的粉丝们
  3. Promise:连接生产代码和消费代码的特殊对象,就像订阅列表

Promise 的基本语法

Promise 对象的构造函数语法如下:

let promise = new Promise(function(resolve, reject) {
  // 执行器代码(生产代码)
});

传入 new Promise 的函数称为执行器(executor),它会自动立即执行。执行器包含生产代码,最终会生成结果。

执行器的两个回调函数

执行器接收两个由 JavaScript 引擎提供的回调函数:

  • resolve(value):操作成功完成时调用,返回结果值
  • reject(error):发生错误时调用,返回错误对象

Promise 的内部状态

Promise 对象创建后具有以下内部属性:

  1. state:初始为 "pending"(等待),最终变为:
    • "fulfilled":当 resolve 被调用时
    • "rejected":当 reject 被调用时
  2. result:初始为 undefined,最终变为:
    • value:当 resolve(value) 被调用时
    • error:当 reject(error) 被调用时

Promise 使用示例

成功示例

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("完成!"), 1000);
});

1 秒后,Promise 状态变为 "fulfilled",结果为 "完成!"

失败示例

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("出错了!")), 1000);
});

1 秒后,Promise 状态变为 "rejected",结果为错误对象

重要特性

  1. 状态不可逆:Promise 状态一旦从 pending 变为 fulfilled 或 rejected,就不可再改变
  2. 单次结果:执行器只能调用一次 resolvereject,后续调用会被忽略
  3. 错误对象:建议使用 Error 对象作为 reject 的参数

消费 Promise:then、catch、finally

then 方法

.then 是处理 Promise 结果的主要方法:

promise.then(
  function(result) { /* 处理成功结果 */ },
  function(error) { /* 处理错误 */ }
);

示例:

let promise = new Promise(resolve => {
  setTimeout(() => resolve("完成!"), 1000);
});

promise.then(
  result => alert(result), // 1秒后显示"完成!"
  error => alert(error) // 不会执行
);

catch 方法

.catch 专门处理错误情况,等同于 .then(null, errorHandler)

let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("出错了!")), 1000);
});

promise.catch(alert); // 1秒后显示错误信息

finally 方法

.finally 类似于常规 try...catch 中的 finally 块,无论 Promise 成功与否都会执行:

new Promise((resolve, reject) => {
  // 执行某些操作
})
.finally(() => {
  // 总是执行的清理代码
})
.then(result => {
  // 处理成功结果
})
.catch(err => {
  // 处理错误
});

finally 特点

  1. 不接受任何参数
  2. 不会处理 Promise 的结果,而是将结果传递给下一个处理程序
  3. 如果返回一个值,该值会被忽略
  4. 如果抛出错误,错误会传递给下一个错误处理程序

实际应用:loadScript 改造

让我们看一个实际的 Promise 应用示例,改造基于回调的脚本加载函数:

回调版本

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;
  
  script.onload = () => callback(null, script);
  script.onerror = () => callback(new Error(`脚本加载失败: ${src}`));
  
  document.head.append(script);
}

Promise 版本

function loadScript(src) {
  return new Promise(function(resolve, reject) {
    let script = document.createElement('script');
    script.src = src;
    
    script.onload = () => resolve(script);
    script.onerror = () => reject(new Error(`脚本加载失败: ${src}`));
    
    document.head.append(script);
  });
}

使用示例

let promise = loadScript("https://example.com/script.js");

promise.then(
  script => alert(`${script.src} 加载成功!`),
  error => alert(`错误: ${error.message}`)
);

Promise 的优势

相比传统回调方式,Promise 具有以下优势:

  1. 自然顺序:先调用函数,再用 .then 处理结果
  2. 多次调用:可以对同一个 Promise 添加多个处理程序
  3. 更好的错误处理:通过链式调用统一处理错误
  4. 代码可读性:避免了回调地狱(callback hell)

Promise 是现代 JavaScript 异步编程的基础,后续的 async/await 语法也是基于 Promise 实现的。掌握 Promise 是成为 JavaScript 开发高手的必经之路。

en.javascript.info Modern JavaScript Tutorial en.javascript.info 项目地址: https://gitcode.com/gh_mirrors/en/en.javascript.info

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆欣瑶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值