上一篇写到了resolvePromise这个方法,这个方法是根据返回不同的x值来进行不同的逻辑处理的。
基本使用
let p = new Promise(function(resplve,reject){ resolve() }) let p2 = p.then(function(){ // return p2 // return 100 // return new Promise(functionl(resolve,reject){ resolve(200) }) }) Promise.all([promise1,promise2,100]).then(function(data){ console.log(data); })复制代码
resolvePromise实现代码
function resolvePromise(promise2,x,resolve,reject){ // 加入返回的x和promise2相等,这样promise2会等待x执行成功或者失败然后才会调用。这样形成了一个自身引用。抛出异常 if(x===promise2){ throw new TypeError('TypeError: Chaining cycle detected for promise #') } let called; // 规范要求 一旦成功了 就不能再调用失败 // x是一个对象或者函数 说明x可能是一个promise if(x!=null && type x ==='object' || typeof x === 'function'){ try{ // 因为当取x.then 的时候可能会抛出异常,所以try捕获一下 let then = x.then if(typeof then ==='function'){ // 为什么不直接x.then执行呢? 因为x.then 的时候 不一定哪一次执行的时候会抛出错误 then.call(x,function(y){ // 因为x执行成功的时候,返回的y可能是原始值、promise、异常,所以这里需要在递归调用一下 if(!called){called = true}else{ return} resolvePromise(promise2,y,resolve,reject) },function(r){ // 错误直接reject if(!called){called = true}else{ return} reject(r) }) }else{ // x为普通值 resolve(x) } }catch(e){ if(!called){called = true}else{ return} reject(e) } }else{ resolve(x) } }复制代码
Promise.catch
catch方法实际就是then方法成功的回调传递的是null
Promise.prototype.catch = function(onRejected){ return this.then(null,onRejected) }复制代码
Promise.resolve
Promise.resolve = function(value){ return new Promise(function(resolve,reject){ resolve(value) }) }复制代码
Promise.reject
Promise.reject = function(reason){ return new Promise(function(resolve,reject){ reject(reason) }) }复制代码
Promise.all
Promise.all = function(promises){ return new Promise(function(resolve,reject){ let arr = []; let i = 0; function processData(index,data){ arr[index] = data; // 这里为什么用一个记数的i,而不是直接用arr.length ===promises.length 判断呢? // 因为当执行all方法的时候,如上所述数组里面的100先执行 这时候索引为2 arr的length 已经为3了 直接满足条件判断,而此时其余的promise还没有执行完成。所以需要一个计数器来进行判断 if(++i === promises.length){ resolve(arr) } } for(let i = 0;i
Promise.race
Promise.race = function(promises){ return new Promise(function(resolve,reject){ for(let i = 0;i
Promise.finally(无论成功还是失败finally里面的方法都会执行)
Promise.prototype.finally = function(cb){ return this.then(function(data){ cb(); return data },function(err){ cb(); throw err; }) }复制代码
Promise.deferred(相当于promise的语法糖,方便书写)
Promise.deferred = Promise.defer = function(){ let dfd = {}; dfd.promise = new Promise((resolve,reject)=>{ dfd.resolve = resolve; dfd.reject = reject; }) return dfd; } // 如下使用 let fs = require('fs') function read(url){ let defer = Promise.defer(); fs.readFile('./1.txt','utf8',function(err,data){ if(err) defer.reject(err) defer.resolve(data) }) return defer.promise; }复制代码
Promise的值穿透(就是then可以不传递参数,交到下一个then来处理)
Promise.prototype.then = function(onFulfilled,onRejected){ // 处理不传递成功 添加默认值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(data){ return data} // 处理不传递失败 添加默认值 onRejected = typeof onRejected ==='function' ? onRejected : function(err){ throw err} //..... }复制代码
Promise测试
可以使用npm库promises-aplus-tests 来进行测试