手写Promise - 实现一个基础的Promise
手写Promise - 实例方法catch、finally
手写Promise - 常用静态方法all、any、resolve、reject、race
上一篇文章手写了一个基础的Promise,我们继续来完善它,为其添加经常用到的catch和finally方法
catch & finally
catch() 方法返回一个Promise,并且处理拒绝的情况。我们知道then方法的第二个参数其实就是干这个用的,catch只是一个别名。
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。和catch一样,也只是对then的一个简写,相当于是传入的函数既是onFulfilled也是onRejected。
有一点需要注意,finally和catch方法只是then的一个别名,实际上返回的还是一个promise,完全可以这样写:promise.then().finally().then().catch().then()
我们把上一章节的代码拷过来,然后向里面添加catch和finally方法。
class WPromise {
static pending = 'pending';
static fulfilled = 'fulfilled';
static rejected = 'rejected';
constructor(executor) {
this.status = WPromise.pending; // 初始化状态为pending
this.value = undefined; // 存储 this._resolve 即操作成功 返回的值
this.reason = undefined; // 存储 this._reject 即操作失败 返回的值
// 存储then中传入的参数
// 至于为什么是数组呢?因为同一个Promise的then方法可以调用多次
this.callbacks = [];
executor(this._resolve.bind(this), this._reject.bind(this));
}
// onFulfilled 是成功时执行的函数
// onRejected 是失败时执行的函数
then(onFulfilled, onRejected) {
// 返回一个新的Promise
return new WPromise((nextResolve, nextReject) => {
// 这里之所以把下一个Promsie的resolve函数和reject函数也存在callback中
// 是为了将onFulfilled的执行结果通过nextResolve传入到下一个Promise作为它的value值
this._handler({
nextResolve,
nextReject,
onFulfilled,
onRejected
});
});
}
// catch方法只有一个参数用于处理错误的情况
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(onFinally, onFinally);
}
_resolve(value) {
// 处理onFulfilled执行结果是一个Promise时的情况
// 这里可能理解起来有点困难
// 当value instanof WPromise时,说明当前Promise肯定不会是第一个Promise
// 而是后续then方法返回的Promise(第二个Promise)
// 我们要获取的是value中的value值(有点绕,value是个promise时,那么内部存有个value的变量)
// 怎样将value的value值获取到呢,可以将传递一个函数作为value.then的onFulfilled参数
// 那么在value的内部则会执行这个函数,我们只需要将当前Promise的value值赋值为value的value即可
if (value instanceof WPromise) {
value.then(
this._resolve.bind(this),
this._reject.bind(this)
);
return;
}
this.value = value;
this.status = WPromise.fulfilled; // 将状态设置为成功
// 通知事件执行
this.callbacks.forEach(cb => this._handler(cb));
}
_reject(reason) {
if (reason instanceof WPromise) {
reason.then(
this._resolve.bind(this),
this._reject.bind(this)
);
return;
}
this.reason = reason;
this.status = WPromise.rejected; // 将状态设置为失败
this.callbacks.forEach(cb => this._handler(cb));
}
_handler(callback) {
const {
onFulfilled,
onRejected,
nextResolve,
nextReject
} = callback;
if (this.status === WPromise.pending) {
this.callbacks.push(callback);
return;
}
if (this.status === WPromise.fulfilled) {
// 传入存储的值
// 未传入onFulfilled时,将value传入
const nextValue = onFulfilled
? onFulfilled(this.value)
: this.value;
nextResolve(nextValue);
return;
}
if (this.status === WPromise.rejected) {
// 传入存储的错误信息
// 同样的处理
const nextReason = onRejected
? onRejected(this.reason)
: this.reason;
nextReject(nextReason);
}
}
}
是的,就是这么简单,现在来测试一下:
function fetchData() {
return new WPromise((resolve, reject) => {
setTimeout(() => {
reject(1);
}, 1000);
});
}
fetchData().finally((data) => {
return data + 10;
}).finally((data) => {
return new WPromise((resolve, reject) => {
reject(data + 10);
});
}).finally((data) => {
console.log(data); // 21
})
以上就是catch和finally的模拟实现,如果理解了then的工作原理的话,理解catch和finally也没啥问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。