手动实现promise.all promise.race

Promise的原理

Promise其实内部也有一个defers队列存放事件,.then的事件就在里面,程序开始执行的时候,.then就已经放入下一个事件,然后后面当异步操作完成时,resolve触发事件队列中的事件,便完成了一个.then操作, 其实到这里我们就可以很快地想出一种解决方案,每次异步操作完成通过resolve触发事件并将事件从事件队列中移除,通过事件队列中的事件的resolve使事件的触发持续下去。

我们可以用十几行代码就可以实现这样的逻辑,实现一个简单的异步编程方案

function P(fn) {
 var value = null;
 var events = [];
 this.then = function(f) {
   events.push(f);
   return this;
 }
 function resolve(newValue) {
   var f = events.shift();
   f(newValue, resolve);
 }
 fn(resolve);
}

function a() {
 return new P(function(resolve) {
   console.log("get...");
   setTimeout(function() {
     console.log("get 1");
     resolve(1);
   }, 1000)
 });
}
a().then(function(value, resolve) {
 console.log("get...");
 setTimeout(function() {
   console.log("get 2");
   resolve(2);
 }, 1000)
}).then(function(value, resolve) {
   console.log(value)
})

控制台得到如下结果:

get... 

get 1

get...

get 2
2

Promise.all()

Promise.all() 它接收一个promise对象组成的数组作为参数,并返回一个新的promise对象。

当数组中所有的对象都resolve时,新对象状态变为fulfilled,所有对象的resolve的value依次添加组成一个新的数组,并以新的数组作为新对象resolve的value。
当数组中有一个对象reject时,新对象状态变为rejected,并以当前对象reject的reason作为新对象reject的reason。

简单实现一个:

Promise.all = function(promises){
          if(!Array.isArray(promises)){
            throw new TypeError('You must pass array')
          }

          return new Promise(function(resolve,reject){
            var result = [],
                count = promises.length;

            function resolver(value){
                resolveAll(value)
            }

            function rejecter(reason){
              reject(reason)
            }

            function resolveAll(value){
              result.push(value)

              if(--count ==0){
                resolve(result)
              }
            }

            for(var i=0;i<promises.length;i++){
              promises[i].then(resolver,rejecter)
            }
          })
        }

Promise.race()

Promise.race() 它同样接收一个promise对象组成的数组作为参数,并返回一个新的promise对象。

与Promise.all()不同,它是在数组中有一个对象(最早改变状态)resolve或reject时,就改变自身的状态,并执行响应的回调。

Promise.race = function(promises){
          if(!Array.isArray(promises)){
            throw new TypeError('You must pass array')
          }

          return new Promise(function(resolve,reject){
            function resolver(value){
              resolve(value)
            }

            function rejecter(reason){
              reject(reason)
            }

            for(var i=0;i<promises.length;i++){
              promises[i].then(resolver,rejecter)
            }
          })
        }

猜你喜欢

转载自blog.csdn.net/guoweifeng0012/article/details/98040926