Promise技术探究

2018-01-13  本文已影响0人  常青_1f93

1.promise简介

  1.1    

          Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才做。

        Promise表示一个异步操作的最终结果。与Promise最主要的交互方法是通过将函数传入它的then方法从而获取得Promise最终的值或Promise最终最拒绝(reject)的原因。

1.2  Promise状态

一个Promise必须处在其中之一的状态:pending, fulfilled 或 rejected.

如果是pending状态,则promise:

可以转换到fulfilled或rejected状态。

如果是fulfilled状态,则promise:

不能转换成任何其它状态。

必须有一个值,且这个值不能被改变。

如果是rejected状态,则promise可以:

不能转换成任何其它状态。

必须有一个原因,且这个值不能被改变。

”值不能被改变”指的是其identity不能被改变,而不是指其成员内容不能被改变。

1.3 then 方法

一个Promise必须提供一个then方法来获取其值或原因。

Promise的then方法接受两个参数:

promise.then(onFulfilled, onRejected)

onFulfilled 和 onRejected 都是可选参数:如果onFulfilled不是一个函数,则忽略之。如果onRejected不是一个函数,则忽略之。

如果onFulfilled是一个函数:它必须在promise fulfilled后调用, 且promise的value为其第一个参数。

它不能在promise fulfilled前调用。不能被多次调用。

如果onRejected是一个函数,它必须在promise rejected后调用, 且promise的reason为其第一个参数。

它不能在promise rejected前调用。不能被多次调用。

onFulfilled 和 onRejected 只允许在 execution context 栈仅包含平台代码时运行. 

onFulfilled 和 onRejected 必须被当做函数调用 (i.e. 即函数体内的 this 为undefined). 

对于一个promise,它的then方法可以调用多次.

当promise fulfilled后,所有onFulfilled都必须按照其注册顺序执行。

当promise rejected后,所有OnRejected都必须按照其注册顺序执行。

then 必须返回一个promise 

promise2 = promise1.then(onFulfilled, onRejected);

如果onFulfilled 或 onRejected 返回了值x, 则执行Promise 解析流程[[Resolve]](promise2, x).

如果onFulfilled 或 onRejected抛出了异常e, 则promise2应当以e为reason被拒绝。

如果 onFulfilled 不是一个函数且promise1已经fulfilled,则promise2必须以promise1的值fulfilled.

如果 OnReject 不是一个函数且promise1已经rejected, 则promise2必须以相同的reason被拒绝.

2.使用promise

let promise = new Promise((resolve, reject) => {

        setTimeout(function(){

                let num =Math.random();

                  if(num<.5){

                        resolve(num);

                  }else{

                        reject('失败');

                  }

        })

});

promise.then(Fulfilled,Rejected)

构造一个Promise实例需要给Promise构造函数传入一个函数。

传入的函数需要有两个形参,两个形参都是function类型的参数。

第一个形参运行后会让Promise实例处于resolve状态,所以我们一般给第一个形参命名为resolve,使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作

第一个形参运行后会让Promise实例处于reject状态,所以我们一般给第一个形参命名为reject,将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作

3 .自己实现promise

const PENDING = 'pending';//初始态

const FULFILLED =  'fulfilled';//成功态

const REJECTED =  'rejected';//失败态

function Promise(executor){

  let self = this;//先缓存当前promise实例

  self.status = PENDING;//设置状态

  //定义存放成功的回调的数组

  self.onResolvedCallbacks = [];

  //定义存放失败回调的数组

  self.onRejectedCallbacks = [];

  //当调用此方法的时候,如果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){ 

    setTimeout(function(){

      //如果是初始态,则转成失败态

      if(self.status == PENDING){

        self.status = REJECTED;

        self.value = reason;//失败的原因给了value

        self.onRejectedCallbacks.forEach(cb=>cb(self.value));

      }

    });

  }

  try{

    //因为此函数执行可能会异常,所以需要捕获,如果出错了,需要用错误 对象reject

    executor(resolve,reject);

  }catch(e){

    //如果这函数执行失败了,则用失败的原因reject这个promise

    reject(e);

  };

}

function resolvePromise(promise2,x,resolve,reject){

  if(promise2 === x){

    return reject(new TypeError('循环引用'));

  }

  let called = false;//promise2是否已经resolve 或reject了

  if(x instanceof Promise){

    if(x.status == PENDING){

      x.then(function(y){

        resolvePromise(promise2,y,resolve,reject);

      },reject);

    }else{

      x.then(resolve,reject);

    }

  //x是一个thenable对象或函数,只要有then方法的对象,

  }else if(x!= null &&((typeof x=='object')||(typeof x == 'function'))){

    //当我们的promise和别的promise进行交互,编写这段代码的时候尽量的考虑兼容性,允许别人瞎写

  try{

    let then = x.then;

    if(typeof then == 'function'){

      //有些promise会同时执行成功和失败的回调

      then.call(x,function(y){

        //如果promise2已经成功或失败了,则不会再处理了

          if(called)return;

          called = true;

          resolvePromise(promise2,y,resolve,reject)

      },function(err){

        if(called)return;

        called = true;

        reject(err);

      });

    }else{

      //到此的话x不是一个thenable对象,那直接把它当成值resolve promise2就可以了

      resolve(x);

    }

  }catch(e){

    if(called)return;

    called = true;

    reject(e);

  }

  }else{

    //如果X是一个普通 的值,则用x的值去resolve promise2

    resolve(x);

  }

}

//onFulfilled 是用来接收promise成功的值或者失败的原因

Promise.prototype.then = function(onFulfilled,onRejected){

  //如果成功和失败的回调没有传,则表示这个then没有任何逻辑,只会把值往后抛

  onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return  value};

  onRejected = typeof onRejected == 'function'?onRejected:reason=>{throw reason};

  //如果当前promise状态已经是成功态了,onFulfilled直接取值

  let self = this;

  let promise2;

  if(self.status == FULFILLED){

    return promise2 = new Promise(function(resolve,reject){

      setTimeout(function(){

        try{

          let x =onFulfilled(self.value);

          //如果获取到了返回值x,会走解析promise的过程

          resolvePromise(promise2,x,resolve,reject);

        }catch(e){

          //如果执行成功的回调过程中出错了,用错误原因把promise2 reject

          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);

          //如果获取到了返回值x,会走解析promise的过程

          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);

        }

    });

  });

  }

}

module.exports =Promise;

4 自己实现promise.all

function gen(times,cb){

  let result = [],count=0;

  return function(i,data){

    result[i] = data;

    if(++count==times){

      cb(result);

    }

  }

}

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);

                    }

         });

}

5. 自己实现 Promise.race

Promise.race =function(promises){

    return new Promise(function(resolve,reject){

            for(let i=0;i<promises.length;i++){

                promises[i].then(resolve,reject);

              }

    });

}

6. 自己实现 Promise.resolve

Promise.resolve =function(value){

        return new Promise(function(resolve){

                resolve(value);

          });

}

7. 自己实现 Promise.resolve

Promise.reject =function(reason){

           return new Promise(function(resolve,reject){

                reject(reason);

          });

}

上一篇下一篇

猜你喜欢

热点阅读