用最简单的实践,实现 Promises/A+ 规范的 Promise
2024-01-13 17:21:05
概述:Promises 的作用与基本概念
Promises/A+ 是一个规范,它定义了 JavaScript 异步编程中 Promise 的行为。Promise 是一个对象,它表示一个异步操作的最终完成或失败及其结果值。使用 Promise 可以使异步编程更加容易和可读。Promises/A+ 规范定义了 Promise 的基本概念,包括:
- 状态: Promise 有三个状态:pending(等待)、fulfilled(已完成)和 rejected(已拒绝)。
- 值: Promise 可以有一个值,它可以是任何类型的数据。
- 回调: Promise 可以注册回调函数,当 Promise 的状态改变时,这些回调函数会被调用。
- 链式调用: Promise 可以被链式调用,这意味着可以将多个 Promise 连接起来,以便在一个 Promise 完成后自动执行下一个 Promise。
Promises/A+ 规范的要求
Promises/A+ 规范定义了 Promise 必须满足的一些要求,这些要求包括:
- Promise 必须有一个 then 方法: then 方法允许注册回调函数,当 Promise 的状态改变时,这些回调函数会被调用。
- Promise 的状态只能从 pending 变成 fulfilled 或 rejected: Promise 的状态一旦改变,就不可再改变。
- Promise 的值只能被设置一次: Promise 的值一旦被设置,就不可再改变。
- Promise 的回调函数必须异步执行: Promise 的回调函数不能在 Promise 的构造函数中执行。
- Promise 必须支持链式调用: Promise 可以被链式调用,这意味着可以将多个 Promise 连接起来,以便在一个 Promise 完成后自动执行下一个 Promise。
实现 Promises/A+ 规范的 Promise
现在,让我们一步步实现一个符合 Promises/A+ 规范的 Promise。首先,我们需要定义 Promise 的状态:
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
接下来,我们需要定义 Promise 的构造函数:
function Promise(executor) {
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state !== PENDING) return;
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach(callback => callback(value));
};
const reject = (reason) => {
if (this.state !== PENDING) return;
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(callback => callback(reason));
};
executor(resolve, reject);
}
Promise 的构造函数接受一个 executor 函数作为参数。executor 函数有两个参数:resolve 和 reject。resolve 函数用于将 Promise 的状态从 pending 变成 fulfilled,reject 函数用于将 Promise 的状态从 pending 变成 rejected。
接下来,我们需要定义 Promise 的 then 方法:
Promise.prototype.then = function(onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function') {
onFulfilled = value => value;
}
if (typeof onRejected !== 'function') {
onRejected = reason => { throw reason; };
}
const promise2 = new Promise((resolve, reject) => {
if (this.state === FULFILLED) {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x);
} catch (error) {
reject(error);
}
}, 0);
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
};
Promise 的 then 方法接受两个参数:onFulfilled 和 onRejected。onFulfilled 函数用于处理 Promise 的值,onRejected 函数用于处理 Promise 的原因。then 方法返回一个新的 Promise,这个新的 Promise 的状态取决于 onFulfilled 和 onRejected 函数的返回值。
最后,我们需要定义一个 resolvePromise 函数:
function resolvePromise(promise, x) {
if (promise === x) {
throw new TypeError('Chaining cycle detected');
}
if (x instanceof Promise) {
x.then(
value => resolvePromise(promise, value),
reason => reject(reason)
);
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
let called = false;
try {
then.call(
x,
value => {
if (called) return;
called = true;
resolvePromise(promise, value);
},
reason => {
if (called) return;
called = true;
reject(reason);
}
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);