Promise的源码实现中有哪些关键步骤
时间: 2023-11-25 15:50:22 浏览: 72
根据Promise的规范,Promise的源码实现中需要包含以下关键步骤:
1. Promise构造函数:Promise构造函数接受一个executor函数作为参数,executor函数有两个参数resolve和reject,分别表示Promise的两种状态,resolve用于将Promise状态从pending变为fulfilled,reject用于将Promise状态从pending变为rejected。
2. Promise状态:Promise有三种状态,分别是pending、fulfilled和rejected。Promise的状态只能从pending变为fulfilled或rejected,且状态一旦改变就不能再次改变。
3. then方法:Promise实例的then方法用于注册回调函数,当Promise状态发生改变时,then方法会被调用。then方法接受两个参数,onFulfilled和onRejected,分别表示Promise状态变为fulfilled和rejected时的回调函数。
4. then方法返回值:then方法返回一个新的Promise实例,该实例的状态由onFulfilled和onRejected的返回值决定。
5. Promise链式调用:Promise的then方法可以链式调用,即一个then方法的返回值可以作为下一个then方法的参数。
6. 异常处理:Promise的异常处理可以通过catch方法实现,catch方法用于捕获Promise链中的异常。
以下是一个简单的Promise实现示例:
```javascript
class Promise {
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onResolvedCallbacks.forEach((fn) => fn());
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
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.status === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'pending') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
catch(onRejected) {
return this.then(null, onRejected);
}
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called = false;
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x, (y) => {
if (called) return;
called = true;
this.resolvePromise(promise2, y, resolve, reject);
}, (r) => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}
}
```
阅读全文