手写 Promise – 实现一个根底的 Promise
手写 Promise – 实例办法 catch、finally
手写 Promise – 罕用静态方法 all、any、resolve、reject、race
先来回顾一下,上一章节之后的代码。
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 时,将 undefined 传入
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);
}
}
}
本章节持续欠缺它,向 Promise 类中增加静态方法 resolve、reject、all、race
。
Resolve、Reject
Promise.resolve(1).then(data => console.log(data)); // 1
Promise.resolve(new Promise((resolve) => resolve(2))).then(data => console.log(data)); // 2
不言而喻,Promise.resolve(value) 只是一个 resolve 的语法糖,返回一个 Promise 对象。须要留神的一点是如果 value 自身就是一个 promise 或者含有 then 办法的对象,那么就间接返回 value。
代码如下:
class WPromise {
...
// reject 的实现是一样的,只是最初调用的是 reject 而不是 resolve 办法
static resolve(value) {
// 判断是否是 thenable 对象
if (value instanceof WPromise || ((typeof value === 'object') && 'then' in value)) {return value;}
return new WPromise((resolve) => resolve(value));
}
...
}
Promise.all
Promise.all(iterable) 办法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“实现(resolved)”或参数中不蕴含 promise 时回调实现(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的起因是第一个失败 promise 的后果。
下面是 MDN 上对于 Promise.all 的解释。
- 承受一个数组,如果数组中有非 promise 对象,则转换成 promise 对象
- 返回一个 promise 实例
- 数组中所有 promise 执行胜利之后才返回胜利状态,并且返回的 promise 的值就是所有 promise 执行胜利的状态值
- 如果有一个 promise 执行失败,则返回失败,并且返回的 promise 的值就是第一个 promise 失败的起因
class WPromise {
...
static all(iterable) {return new WPromise((resolve, reject) => {const ret = [];
let count = 0;
Array.from(iterable).forEach((item, index) => {WPromise.resolve(item).then(data => {ret[index] = data;
count++;
if (count === iterable.length) {resolve(ret);
}
}, reject);
});
});
}
...
}
Promise.race
Promise.race(iterable) 办法返回一个 promise,一旦迭代器中的某个 promise 解决或回绝,返回的 promise 就会解决或回绝。
这个没啥好说的,间接就是返回一个 Promise 就完事。
class WPromise {
...
static race(iterable) {return new WPromise((resolve, reject) => {Array.from(iterable).forEach(item => {WPromise.resolve(item).then(resolve, reject);
});
});
}
...
}
以上内容,根本就是所有的 Promise 的内容了。当然还有很多细节的方面没有解决,如果异样解决、边界断定等等。
更多:上述模仿 Promise 的残缺代码