返回
用简单代码认识Promise的运行原理
前端
2023-09-13 02:09:38
Promise的基本概念
Promise,通常被翻译成承诺或诺言,它是一种异步编程的解决方案。在 Promise 出现之前,通常的做法是使用回调函数,但随着JavaScript代码变得越来越复杂,回调函数很容易陷入“回调地狱”,使得代码难以维护。
Promise 的出现改变了这一切。它提供了一个统一的、基于状态的异步编程接口,使代码更易于理解和管理。
Promise的执行原理
为了更好地理解 Promise 的工作原理,我们先看看一段手写 Promise 的源码:
class Promise {
constructor(executor) {
this.state = "pending"; // 初始状态为等待中
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
// 立即执行执行器
executor(resolve, reject);
}
resolve(value) {
if (this.state !== "pending") return;
this.state = "fulfilled"; // 状态变为成功
this.value = value; // 保存成功的值
this.onFulfilledCallbacks.forEach(callback => callback(value)); // 调用成功的回调函数
}
reject(reason) {
if (this.state !== "pending") return;
this.state = "rejected"; // 状态变为失败
this.reason = reason; // 保存失败的原因
this.onRejectedCallbacks.forEach(callback => callback(reason)); // 调用失败的回调函数
}
then(onFulfilled, onRejected) {
// 如果没有传递成功回调,则使用默认的处理函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
// 如果没有传递失败回调,则使用默认的处理函数
onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason };
const promise = new Promise((resolve, reject) => {
// 注册成功的回调函数
this.onFulfilledCallbacks.push(() => {
// 调用成功回调函数
try {
const result = onFulfilled(this.value);
// 如果成功回调函数返回一个 Promise,则需要等待这个 Promise 完成
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
// 如果成功回调函数返回一个普通值,则直接调用 resolve
resolve(result);
}
} catch (error) {
// 如果成功回调函数抛出错误,则直接调用 reject
reject(error);
}
});
// 注册失败的回调函数
this.onRejectedCallbacks.push(() => {
// 调用失败回调函数
try {
const result = onRejected(this.reason);
// 如果失败回调函数返回一个 Promise,则需要等待这个 Promise 完成
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
// 如果失败回调函数返回一个普通值,则直接调用 resolve
resolve(result);
}
} catch (error) {
// 如果失败回调函数抛出错误,则直接调用 reject
reject(error);
}
});
});
return promise;
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
}
Promise的使用示例
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功的值"); // 1秒后将 Promise 的状态变为成功
}, 1000);
});
promise.then((value) => {
console.log("成功回调函数执行,返回值:" + value);
}).catch((reason) => {
console.log("失败回调函数执行,原因:" + reason);
});
在上面的示例中,我们创建了一个 Promise,并在 1 秒后将它的状态变为成功。然后,我们使用 then() 方法注册了成功的回调函数,并在回调函数中打印成功的值。同时,我们还注册了 catch() 方法,用于处理 Promise 失败的情况。
当这段代码执行时,它将在 1 秒后打印出"成功的值"。
总结
Promise 提供了一种更简单、更优雅的方式来处理异步编程。它使代码更易于理解和管理,并避免了陷入“回调地狱”。通过学习Promise 的基本概念和使用示例,您就可以在自己的项目中使用 Promise 来编写更优雅的异步代码。