参考https://github.com/chunpu/promise/blob/master/promise.jsgit
我的认为原博的实现有点问题 在next函数的实现上, 会致使无限的调用github
看看通常Promise的用法数组
promise = new Promise(function(resolve, reject) { //... resolve(1); //... }) .then(function(val){}, functioin(err){}) .then(function(val){}, functioin(err){})
显然要实现的功能是这样的
Promise对象有then方法
Promise对象接受一个参数fn(resolve, reject)
Promise能够连续的then调用promise
function Promise(resolver) { var queue = [];//链式调用数组 resolver(resolve, reject); //state 0 是resolve function next(state, val){ var arr; if(arr = queue.shift()){ arr[state](val); } } function resolve(x){ next(0, x) } function reject(reason){ next(1, reason); } //Promise最明显的特征 是能够then then接收两个参数 //then就是将传入的函数放入队列中 this.then = function(resolve, reject){ queue.push([resolve, reject]); //resovle reject 这两个参数也都是函数 } } var p = new Promise(function(resolve){ resolve('ok') }) p.then(function(x){ console.log(x); })
有个问题 那就是建立一个Promise对象的时候就调用了 resolver(resolve, reject); 也就是调用了resolve('ok') 也就是调用了next 也就是使queue函数出队列并执行函数
可是这个时候 queue 尚未push任何值 执行不能继续 毕竟这个是在Promise对象完成建立以后才调用then测试
为了使next在then中的函数所有进到队列以后再执行 用一个setTimeout把 next中的逻辑包裹this
function Promise(resolver) { var queue = []; resolver(resolve, reject); function next(state, val){ var arr; //为了使resolve晚于 then 执行 暂时用一个setTimeout setTimeout(function(){ if(arr = queue.shift()){ arr[state](val); } }, 0); } function resolve(x){ next(0, x); } function reject(reason){ next(1, reason); } this.then = function(resolve, reject){ queue.push([resolve, reject]); } } var p = new Promise(function(resolve){ setTimeout(function(){ resolve('ok') },1200); }).then(function(data){ console.log(data); })
不过咱们知在一个then中 return 可能不单单是一个简单地的value , 有可能再次返回一个Promise对象 而下一个then中resolve函数的的data是这个Promise对象resolve()的值code
听起来很复杂 针对return一个Promise对象的状况 就是调用这个对象的then
而后再次进入next 而next的参数就是返回的Promise对象的resolve的值对象
function Promise(resolver) { var queue = []; //链式调用数组 resolver(resolve, reject); //state 0 是resolve function next(state, val) { var arr; var chainRs; setTimeout(function() { if (arr = queue.shift()) { chainRs = arr[state](val); if(!chainRs) return; //某一个resolve函数返回的又是一个Promise对象 if (chainRs && typeof chainRs.then == 'function') { chainRs.then(resolve, reject); } else { //resolve函数返回一个普通的值 resolve(chainRs) //.then(resolve, reject); } } }, 0); } function resolve(x) { next(0, x); } function reject(reason) { next(1, reason); } //Promise最明显的特征 是能够then then接收两个参数 //then就是将传入的函数放入队列中 this.then = function(resolve, reject) { queue.push([resolve, reject]); //resovle reject 这两个参数也都是函数 return this; } } Promise.resolve = Promise.cast = function(x) { return new Promise(function(resolve) { resolve(x); }) }
测试队列
var p = new Promise(function(resolve) { setTimeout(function() { resolve('ok') }, 1200); }).then(function(data) { console.log(data); // return 555; return new Promise(function(resolve){ setTimeout(function(){ resolve('wahaha'); }, 2200); }) }) .then(function(data) { console.log('2nd then', data); return 666; }) .then(function(data) { console.log('3rd then', data); });
完善 增长Promise.all() Promise.resolve()
Promise.resolve = Promise.cast = function(x) { return new Promise(function(resolve) { resolve(x); }) } Promise.all = function(promises){ var len = promises.length; var results = []; return new Promise(function(resolve){ promises.forEach(function(p, i){ p.then(function(data){ results[i] = data; len--; if(len == 0){ resolve(results); } }, function(err){ console.log(err); }); }); }); } //================================= Promise.resolve(999) .then(function(data){ console.log(data); return new Promise(function(resolve, reject){ // resolve('xixi'); reject('xixi'); }) }).then(function(data){ console.log(data); },function(err){ console.log(err); }) Promise.all([ new Promise(function(resolve){ setTimeout(function(){ resolve(111); }, 1000); }), new Promise(function(resolve){ resolve(222); }) ]).then(function(results){ console.log(results); })