Promise 思考及强化实现

Promise 思考及强化实现

标签(空格分隔): ES6 Promisejavascript


本文原创,如需转载请注明出处前端

我须要什么

作了Sudoku项目后,很头疼的问题就是代码维护,很大一部分缘由是回调嵌套太多,影响代码的可读性,增长了维护难度,尤为是后端的数据库操做,用nodeJs一般会写许多回调嵌套。此次终于打算揭竿起义。java

第二次修改,废话很少说,直接进入正题
先看下面这段代码node

function do(){
        //查找数据库
        setTimeout(()=>{
            console.log('收到数据');
            //修改字段,并保存
            setTimeout(()=>{
                console.log('保存成功')
                //发送响应给前端
            },1000)
            setTimeout
        },1000)
    }
    do()

模拟了很是简单的一个从前端接受请求到发送响应回到前端的过程,
这个代码是很是简单的,不过看起来并非,并且一旦需求更复杂,
这样风格的代码确定会让我很是头疼es6

我须要的代码风格

  1. 每一个异步过程独立成块,再也不是嵌套风格
  2. 异步返回结果的处理过程独立于异步过程
  3. 可伸缩,直接扩展异步结果处理过程,并不与以前的混在一块儿,实现细分,独立成块
  4. 每一个异步过程存在依赖

好吧,发现promise知足个人全部需求,拿来现成用?这一点都很差玩
,因此研究了一下promise的用法,下面是我简易的需求说明数据库

需求说明(参考ES6的实现效果)

  1. 每一个promise实例 resolve动做 reject动做
  2. promise实例 then方法注册resolve回调,reject回调
  3. A实例执行完回调,then()会返回一个B实例
  4. B实例跟A同样,一样有 resolve动做 reject动做
  5. 调用B的then()方法一样会注册resolve回调,reject回调
  6. 影响B动做的因素有4个(下面详细讲解)
  7. 有catch同then同样,可是只能注册一个错误回调
  8. a实例如过程上依赖于另一个b实例,则可被当作其resolve参数传递,而且b实例成功好事滚粗依赖于 a 的状态
  9. 一旦实例状态发生改变,状态不会再改变

影响B实例的因素

1.A的resolve回调和reject回调是否有异常抛出

是:B执行reject动做 否:B执行resolve动做

2.A的reject动做是否有回调

是:回到1. 、       否:B执行reject动做

3.A的resolve动做是否有回调

是:回到1           否: B执行resolve动做

4.A的回调中return 另外一个promise实例C

C resolve: B resolve    C reject: B reject

具体实现

Promise实例全部的属性后端

class Promise{
    //构造函数 fn为构建实例的异步过程
    constructor(fn){
        //必须为函数类型
		if(typeof fn !== 'function') throw new Error('not a function');
		this.success = [];
		this.sucArg = null;
		this.fail = [];
		this.failArg = null;
		this.state = 0;
		this.parent = null;
		//fork promise分支
		this.fork = [];
		//传递的error
		setTimeout(()=>{
			fn(myPromise.resolve.bind(this),myPromise.reject.bind(this))	
		},0);
    }
}

Promise实例的方法,then(),catch()promise

//onFulfilled成功处理函数,onRejected滚粗处理函数
    then(onFulfilled,onRejected){
        /*参数格式限制*/
		let fork = new myPromise(()=>{});
		if(typeof onFulfilled ==='function'){
			this.success.push(onFulfilled);
			fork.forkSuc = onFulfilled;
		}
		if(typeof onRejected ==='function'){
			this.fail.push(onRejected);
			fork.forkRej = onRejected;
		} 
		this.fork.push(fork);
		return fork;
    }
    catch(onRejected){
        //参数必须函数
		let fork = new myPromise(()=>{});
		if(typeof onRejected !=='function') return this;
		this.fail.push(onRejected);
		fork.forkRej = onRejected;	
		this.fork.push(fork);
		return fork;
    }

Promise静态方法resolve,reject异步

static resolve(value){
        if(this.state!==0) return;
		//参数不是myPromise实例
		if(value instanceof myPromise){
			//如参数是一个promise实例
			value.parent = this;
			if(value.state===1){
				//实例状态为成功
				myPromise.resolve.call(this,value.successArg);
			}else if(value.state===-1){
				//实例状态为失败
				myPromise.reject.call(this,value.failArg);
			}
		}else{
			if(!this.success.length){
				for(let fn of this.fork){
					myPromise.resolve.call(fn,value);
				}
			}else{
				this.sucArg = value;
				let cur = 0;
				for(let fn of this.success){	if(this.fork.length&&fn===this.fork[cur].forkSuc){
						let error,preArg,bool;
						try{
							preArg = fn(value);
							if(preArg instanceof myPromise){
								let index = cur;
								bool = true;
								preArg.success.push(()=>{	myPromise.resolve.call(this.fork[index],preArg.sucArg);
								});
								preArg.fail.push(()=>{			myPromise.reject.call(this.fork[index],preArg.failArg);
								})
							}
						}catch(err){
							error = err||null; 
						}
						if(!bool){
							error? myPromise.reject.call(this.fork[cur],error): myPromise.resolve.call(this.fork[cur],preArg);
						}
						cur++;
					}else{
						fn(value);
					}
				}
			}
			//当前promise变为fulfilled
			this.state = 1;
			//如存在parent,则parent.resolve(value)
			if(this.parent) myPromise.resolve.call(this.parent,value);
		}
    }
    static reject(value){
        if(this.state!==0) return;
		//参数是myPromise实例
		if(value instanceof myPromise){
			value.parent = this;
			myPromise.reject.call(this);
		}else{
			if(!this.fail.length){
				for(let fn of this.fork){
					myPromise.reject.call(fn,value)
				}
			}else{
				this.failArg = value;
				let cur = 0;
				for(let fn of this.fail){
		if(this.fork.length&&fn===this.fork[cur].forkRej){
						let error,preArg,bool;
						try{
							preArg = fn(value);
							if(preArg instanceof myPromise){
								let index = cur;
								bool = true;
								preArg.success.push(()=>{	myPromise.resolve.call(this.fork[index],preArg.sucArg);
								});
								preArg.fail.push(()=>{	myPromise.reject.call(this.fork[index],preArg.failArg);
								})
							}
						}catch(err){
							error = err||null; 
						}
						if(!bool){
							error? myPromise.reject.call(this.fork[cur],error): myPromise.resolve.call(this.fork[cur],preArg);
						}
						cur++;
					}else{
						fn(value);
					}	
				}
			}
			this.state = -1;

			if(this.parent) myPromise.reject.call(this.parent,value);
		}
        
    }

好了,就这么多,这是个简易的Promise实现,若有错误,或者什么建议
QQ:387857274欢迎讨论函数

相关文章
相关标签/搜索