在须要多个操做的时候,会致使多个回调函数嵌套,致使代码不够直观,就是常说的回调地狱,一般经过promise来解决Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 何时会用到过一段时间?答案是异步操做,异步是指可能比较长时间才有结果的才作,例如网络请求、读取本地文件等数组
构造函数初始化逻辑
const PENDING = 'pending';//初始态 const FULFILLED = 'fulfilled';//初始态 const REJECTED = 'rejected';//初始态 let self = this;//先缓存当前promise实例 self.status = PENDING;//设置状态 self.onResolvedCallbacks = [];//定义存放成功的回调的数组 self.onRejectedCallbacks = []; //定义存放失败回调的数组
executor执行器,包含两个参数,分别是resolve 解决和reject 拒绝,new Promise这个executor就会执行Promise有三个状态:初始化状态为pending,成功状态为fulfilled,失败状态rejected,若是代码一旦成功就不会走向失败,若 一直pending 永远不给你明确的答复promise
当调用如下方法的时候,若是promise状态为pending的话能够转成成功态,若是已是成功态或者失败态了,则什么都不作缓存
function resolve(value){ if(value!=null &&value.then&&typeof value.then == 'function'){ return value.then(resolve,reject); } setTimeout(function(){ if(self.status == PENDING){ self.status = FULFILLED; self.value = value; self.onResolvedCallbacks.forEach(cb=>cb(self.value)); } }) } function reject(reason){ //2.1.2 setTimeout(function(){ if(self.status == PENDING){ self.status = REJECTED; self.value = reason; self.onRejectedCallbacks.forEach(cb=>cb(self.value)); } }); } }
由于此函数执行可能会异常,因此须要捕获,若是出错了,须要用错误对象reject,若是这函数执行失败了,则用失败的缘由reject这个promise,须要用try...catch(e)...进行处理
try{ executor(resolve,reject); }catch(e){ reject(e); };
Promise的解析过程
function resolvePromise(promise2,x,resolve,reject){ if(promise2 === x){ return reject(new TypeError('循环引用')); } let called = false; if(x instanceof Promise){ if(x.status == PENDING){ x.then(function(y){ resolvePromise(promise2,y,resolve,reject); },reject); }else{ x.then(resolve,reject); } }else if(x!= null &&((typeof x=='object')||(typeof x == 'function'))){ try{ let then = x.then; if(typeof then == 'function'){ then.call(x,function(y){ if(called)return; called = true; resolvePromise(promise2,y,resolve,reject) },function(err){ if(called)return; called = true; reject(err); }); }else{ resolve(x); } }catch(e){ if(called)return; called = true; reject(e); } }else{ resolve(x); } }
then
方法就是用来指定Promise 对象的状态改变时肯定执行的操做,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)
此方法中,若是成功和失败的回调没有传,则表示这个then没有任何逻辑,只会把值日后抛
Promise.prototype.then = function(onFulfilled,onRejected){ onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return value}; onRejected = typeof onRejected == 'function'?onRejected:reason=>{throw reason}; let self = this; let promise2; if(self.status == FULFILLED){ return promise2 = new Promise(function(resolve,reject){ setTimeout(function(){ try{ let x =onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); } if(self.status == REJECTED){ return promise2 = new Promise(function(resolve,reject){ setTimeout(function(){ try{ let x =onRejected(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); } if(self.status == PENDING){ return promise2 = new Promise(function(resolve,reject){ self.onResolvedCallbacks.push(function(){ try{ let x =onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }); self.onRejectedCallbacks.push(function(){ try{ let x =onRejected(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }); }); } }
promise的链式调用
then
可使用链式调用的写法缘由在于,每一次执行该方法时老是会返回一个Promise
对象catch
只是 promise.then(undefined, onRejected); 方法的一个别名而已。 也就是说,这个方法用来注册当promise对象状态变为Rejected时的回调函数
catch原理就是只传失败的回调
Promise.prototype.catch = function(onRejected){ this.then(null,onRejected); }
Promise.all
接收一个 promise对象的数组做为参数,当这个数组里的全部promise对象所有变为resolve或reject状态的时候,它才会去调用 .then 方法
Promise.all = function(promises){ return new Promise(function(resolve,reject){ let done = gen(promises.length,resolve); for(let i=0;i<promises.length;i++){ promises[i].then(function(data){ done(i,data); },reject); } }); }
Promise.race
只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理
Promise.race = function(promises){ return new Promise(function(resolve,reject){ for(let i=0;i<promises.length;i++){ promises[i].then(resolve,reject); } }); }
别人提供 给你一个方法,须要你传入一个promise,但你只有一个普通的值,你就能够经过这个方法把这个普通的值(string number object)转成一个promise对象
返回一个马上成功的promise
Promise.resolve = function(value){ return new Promise(function(resolve){ resolve(value); }); }
返回一个马上失败的promise
Promise.reject = function(reason){ return new Promise(function(resolve,reject){ reject(reason); }); }