返回
Promise 实现原理剖析:精简高效的代码解析
前端
2023-11-04 02:49:46
前言
Promise 是 JavaScript 中处理异步编程的利器,它可以帮助我们编写更易读、更易维护的代码。然而,很多同学在学习 Promise 时,知其然却不知其所以然,对其中的用法理解不了。
本系列文章将由浅入深逐步实现 Promise,并结合流程图、实例以及动画进行演示,达到深刻理解 Promise 用法的目的。
本文适合对 Promise 的用法有所了解的人阅读,如果还不清楚,请自行查阅相关资料。
Promise 的基础实现
首先,我们来看一个最简单的 Promise 实现:
class Promise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
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 promise2 = new Promise((resolve, reject) => {
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
} else if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
}
});
return promise2;
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(value => {
onFinally();
return value;
}, reason => {
onFinally();
throw reason;
});
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise!'));
}
if (x instanceof Promise) {
x.then(value => {
resolvePromise(promise2, value, resolve, reject);
}, reason => {
reject(reason);
});
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x, value => {
resolvePromise(promise2, value, resolve, reject);
}, reason => {
reject(reason);
});
} else {
resolve(x);
}
} catch (err) {
reject(err);
}
} else {
resolve(x);
}
}
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, world!');
}, 2000);
});
promise.then(value => {
console.log(value); // 'Hello, world!'
});
这个 Promise 实现非常简单,它只有最基本的功能,但它已经足够让我们理解 Promise 的工作原理。
Promise 的状态
Promise 有三种状态:
- pending :表示 Promise 还未完成,即还没有调用
resolve
或reject
方法。 - fulfilled :表示 Promise 已完成,并且成功执行了
resolve
方法。 - rejected :表示 Promise 已完成,并且执行了
reject
方法。
Promise 的方法
Promise 有以下几个方法:
- resolve(value) :将 Promise 的状态改为 fulfilled ,并传入一个值。
- reject(reason) :将 Promise 的状态改为 rejected ,并传入一个原因。
- then(onFulfilled, onRejected) :在 Promise 完成时执行指定的回调函数。如果 Promise 的状态是 fulfilled ,则执行
onFulfilled
函数;如果 Promise 的状态是 rejected ,则执行onRejected
函数。 - catch(onRejected) :在 Promise 完成时执行指定的回调函数。如果 Promise 的状态是 fulfilled ,则忽略该回调函数;如果 Promise 的状态是 rejected ,则执行该回调函数。
- finally(onFinally) :在 Promise 完成时执行指定的回调函数。无论 Promise 的状态是 fulfilled 还是 rejected ,都会执行该回调函数。
Promise 的使用示例
以下是一个 Promise 的使用示例:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, world!');
}, 2000);
});
promise.then(value => {
console.log(value); // 'Hello, world!'
});
在这个示例中,我们首先创建了一个 Promise 对象,然后在 2 秒后调用 resolve
方法,将 Promise 的状态改为 fulfilled ,并传入一个值 "Hello, world!"
。然后,我们使用 then
方法添加了一个回调函数,该回调函数将在 Promise 完成时执行。当 Promise 完成时,回调函数被执行,并且将 "Hello, world!"
打印到控制台。
总结
本文介绍了 Promise 的基础实现,包括 Promise 的状态、方法和使用示例。希望通过本文,你能够对 Promise 有一个更深入的理解。