标签(空格分隔): ES6 Promisejavascript
本文原创,如需转载请注明出处前端
作了Sudoku项目后,很头疼的问题就是代码维护,很大一部分缘由是回调嵌套太多,影响代码的可读性,增长了维护难度,尤为是后端的数据库操做,用nodeJs一般会写许多回调嵌套。此次终于打算揭竿起义。java
第二次修改,废话很少说,直接进入正题
先看下面这段代码node
function do(){ //查找数据库 setTimeout(()=>{ console.log('收到数据'); //修改字段,并保存 setTimeout(()=>{ console.log('保存成功') //发送响应给前端 },1000) setTimeout },1000) } do()
模拟了很是简单的一个从前端接受请求到发送响应回到前端的过程,
这个代码是很是简单的,不过看起来并非,并且一旦需求更复杂,
这样风格的代码确定会让我很是头疼es6
- 每一个异步过程独立成块,再也不是嵌套风格
- 异步返回结果的处理过程独立于异步过程
- 可伸缩,直接扩展异步结果处理过程,并不与以前的混在一块儿,实现细分,独立成块
- 每一个异步过程存在依赖
好吧,发现promise知足个人全部需求,拿来现成用?这一点都很差玩
,因此研究了一下promise的用法,下面是我简易的需求说明数据库
- 每一个promise实例 resolve动做 reject动做
- promise实例 then方法注册resolve回调,reject回调
- A实例执行完回调,then()会返回一个B实例
- B实例跟A同样,一样有 resolve动做 reject动做
- 调用B的then()方法一样会注册resolve回调,reject回调
- 影响B动做的因素有4个(下面详细讲解)
- 有catch同then同样,可是只能注册一个错误回调
- a实例如过程上依赖于另一个b实例,则可被当作其resolve参数传递,而且b实例成功好事滚粗依赖于 a 的状态
- 一旦实例状态发生改变,状态不会再改变
是:B执行reject动做 否:B执行resolve动做
是:回到1. 、 否:B执行reject动做
是:回到1 否: B执行resolve动做
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欢迎讨论函数