手写Promise - 常用静态方法all、resolve、reject、race

手写Promise - 实现一个基础的Promise
手写Promise - 实例方法catch、finally
手写Promise - 常用静态方法all、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的解释。

  1. 接受一个数组,如果数组中有非promise对象,则转换成promise对象
  2. 返回一个promise实例
  3. 数组中所有promise执行成功之后才返回成功状态,并且返回的promise的值就是所有promise执行成功的状态值
  4. 如果有一个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的完整代码

你可能感兴趣的:(手写Promise - 常用静态方法all、resolve、reject、race)