欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用es6实现一个promsie

程序员文章站 2022-06-30 19:13:30
...

Promise 使用方法: https://www.runoob.com/w3cnote/javascript-promise-object.html

直接上代码,相关的解释都在代码的注释里面,这里以minPromise 代替 Promise:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>

<script type="text/javascript">
	class minPromise {
		/** 
		比如 
		var p = new minPromise ((resolve, reject)=> {
			 // 这里是处理的代码,脑补
		})
		那么 executor 就是 (resolve, reject) => { ... }
		**/
		constructor(executor){
			// executor 必须是 function 类型
			if (typeof executor !== 'function') {
		      throw new Error('Executor must be a function');
		    }
		    
		    // 初始状态是 PENDING
		 	this.state = 'PENDING';
		    this.chained = [];

			const resolve = res => {
				// 如果状态不是 PENDING 那就不进行处理了
		    	if (this.state !== 'PENDING') {
		        	return;
		      	}

		      	// 假如说res这个对象有then的方法,我们就认为res是一个promise
		      	if (res != null && typeof res.then === 'function') {
		        	return res.then(resolve, reject);
		      	}

		      	this.state = 'FULFILLED';
		      	this.internalValue = res;
		      	// 这里用到 解构 相当于 for(let item of this.chainer) 然后 { onFulfilled }  = item , 下同
		      	for (let { onFulfilled } of this.chained) {
		        	onFulfilled(res);
		      	}
		    };

	     	const reject = err => {
		      	if (this.state !== 'PENDING') {
	       	 		return;
		      	}
		      	this.state = 'REJECTED';
		      	this.internalValue = err;
		      	for (const { onRejected } of this.chained) {
		        	onRejected(err);
		      	}
		    };

		    // 这里相当于函数初始运行 利用了构造函数自动执行的特性
		    try{
				executor(resolve, reject);
		    }catch(err){
		    	reject(err);
		    }
		}

		// 状态是 FULFILLED 或者 REJECTED 说明已经执行完 resolve 方法, internalValue 也已经有值了,可以直接执行
		// 状态是 PENDING 说明 resolve 的方法是异步的, 就先把  onFulfilled, onRejected 事件放到 chained 里面,存起来,等 resolve 的时候在执行
	   

	   // 如果不需要then的链式调用, 用这个then就可以
	   //  then(onFulfilled, onRejected) {
		  //   if (this.state === 'FULFILLED') {
		  //     	onFulfilled(this.internalValue);
		  //   } else if (this.state === 'REJECTED') {
		  //     onRejected(this.internalValue);
		  //   } else {
		  //     	this.chained.push({ onFulfilled, onRejected });
		  //   }
	  	// }

	  	// 需要then的链式调用的话 让then返回 Promise 就行
	  	then(onFulfilled, onRejected) {
		    return new minPromise((resolve, reject) => {
		      // 这里把	onFulfilled  onRejected 封装了下 是因为 resolve(onFulfilled(res))  或者 reject(onRejected(err)) 执行的时候 有可能报错,做了错误兼容处理
		      const _onFulfilled = res => {
		        try {
		          //注意这里resolve有可能要处理的是一个promise
		          resolve(onFulfilled(res));
		        } catch (err) {
		          reject(err);
		        }
		      };
		      const _onRejected = err => {
		        try {
		          reject(onRejected(err));
		        } catch (_err) {
		          reject(_err);
		        }
		      };
		      if (this.state === 'FULFILLED') {
		        _onFulfilled(this.internalValue);
		      } else if (this.state === 'REJECTED') {
		        _onRejected(this.internalValue);
		      } else {
		        this.chained.push({ onFulfilled: _onFulfilled, onRejected: _onRejected });
		      }
		    });
	    },
	    // resolve方法 相当于返回一个Promise对象
	    resolve(value) {
	    	return new minPromise(value => {
	    		resolve(value);
	    	})
	    },
	    reject(reason) {
	        return new minPromise((resolve, reject) => {
	            reject(reason);
	        });
	    },
	    // 全部成功的时候返回的是一个结果数组,失败的时候 会直返回失败
		all(promiseArr) {
		    return new minPromise((res, rej)  => {
		        // promiseArr 所有的值都看一下
		        var arr = [];
		        var times = 0;
		        processResult =  (index, result) =>{
		            arr[index] = result;
		            times++;
		            // arr.length == promiseArr.length, 代表全部都 resolve 成功
		            if (times ==  promiseArr.length) {
		            	// 在这里执行最后的 resolve
		                res(arr);
		            }
		        };

		        for (let i = 0; i < promiseArr.length; i++) {
		            var oPromise = promiseArr[i];
		            // 是 promise
		            if (typeof oPromise.then == 'function') {
		                oPromise.then((val) =>{
		                	// then 成功后把值存下来
		                    processResult(i, val)
		                }, (reason) =>{
		                    // 不成功 直接 reject
		                    rej(reason);
		                })
		            }else {
		                processResult(i, oPromise);
		            }
		        }
		    });
		},

	    // 哪个实例获得结果最快,就返回那个结果,不管结果本身是成功还是失败;
	    race(promiseArr) {
		    return new minPromise((resolve, reject) => {
		        promiseArr.forEach((promise) => {
		           promise.then(resolve, reject);
		        });
		    });
		},

	}

	// 测试非链式调用
	let p = new minPromise(resolve => {
  		setTimeout(() => resolve('Hello'), 100);
	});

	p.then(res => console.log(res));

	p = new minPromise((resolve, reject) => {
	  setTimeout(() => reject(new Error('woops')), 100);
	});

	p.then(() => {}, err => console.log('Async error:', err.stack));


	// 测试链式调用
	let p2 = new minPromise(resolve => {
	  setTimeout(() => resolve('World'), 100);
	});

	p2.
  	then(res => new minPromise(resolve => resolve(`Hello, ${res}`))).
 	then(res => console.log(res));

</script>

</body>
</html>

  参考: https://segmentfault.com/a/1190000014440641   , https://juejin.im/post/5aa7868b6fb9a028dd4de672#heading-9