美文网首页js
Promise内部实现的原理

Promise内部实现的原理

作者: Wang_Yong | 来源:发表于2018-09-12 16:22 被阅读0次

    第一明确Promise是干什么用的

    promise用来实现一步操作,解决了回调地狱的问题
    所谓的promise简单来说就是一个容器,里面保存着某些未来才结束的事件(通常是一个异步操作)的结果。
    从语法上来讲,Promise是一个对象,从它可以获取一步操作的消息。Promise对象的状态不受外部影响。
    promise上面的方法

    Promise.all()
    Promise.race()
    Promise.resolve()
    Promise.reject()
    Promise.prototype.catch()
    Promise.prototype.finally()
    Promise.prototype.then()
    

    Promise.prototype.catch()方法是.then(null,rejection)的别名。用于指定发生错误时的回调函数

    第二解析一下Promise的实现原理(源码)

    const PENDING = 'pending'; //初始状态
    const FULFILLED = 'fulfilled'; // 成功状态
    const REJECTED = 'rejected'; // 成功
    function Promise(extutor){
      let self = this;
      self.status = PENDING; // 设置状态
      // 存放成功回调的数组
      self.onResolveCallbacks = [];
      // 存放失败回调的数组
      self.onRejectedCallbacks = [];
      function resolve(value){
        if(self.status === PENDING){
          self.status = FULFILLED;
          self.value = value;
          self.onResolveCallbacks.forEach(cb => cd(self.value))
        }
      } 
      function reject(reason){
        if(self.status === PENDING){
          self.status = REJECTED;
          self.value = reason;
          self.onRejectCallbacks.forEach(cb => cd(self.value))
        }
      } 
      try{
        excutor(resolve, reject)
      } catch(e) {
        reject(e)
      }
    }
    

    then方法在调用then方法中传进去的时候是两个函数,分别对应的是promise中的一步方法成功和失败的回调

    Promise.prototype.then = function(onFulfilled, onRejected){
      // 如果成功和失败的回调没有传,表示这个then没有任何逻辑,只负责把值往后抛
      onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : value => value
      onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason }
      let self = this;
      let promise2;
      // 实现链式调用,每一种状态都要返回的是一个promise实例
      if(self.status == FULFILLED){ // 如果promise状态已经是成功态,onFulfilled直接取值
        return  promise2 = new Promise(function(resolve, reject){
          setTimeout(function(){  // 保证返回的promise是异步
            try{
              onFulfilled(self.value)
            } catch (e){
              //  如果执行成功的回调过程中出错,用错误原因把promise2 reject
              reject(e)
            }
          })
        })
      }
      if( self.status == REJECTED){
        return promise2 = new Promise(function(){
          setTimeout(function(){
            try{
              onFulfilled(self.value)
            } catch (e){
              reject(e)
            }
          })
        })
      }
      if(self.status === PENDING){
        return promise2 = new Promise(function(resolve, reject){
          // pending 状态时就会把所有的回调函数都添加到实例中的两个堆栈中暂存,等状态改变后依次执行,其实这个过程就是观察者模式
          self.onResolveCallbacks.push(function(){
            setTimeOut(function(){
              try{
                onFulfilled(self.value)
              } catch(e){
                reject(e)
              }
            })
          })
        })
        self.onRejectCallbacks.push(){
          setTimeOut(function(){
            try{
              onRejected(self.value)
            } catch(e){
              reject(e)
            }
          })
        }
      }
    }
    

    // 写到这,我也知识理解的一部分

    以上只是支持一次then的调用,现实中我们会有这种需求

    const p = new Promise(function(resolve, reject){
      if(/*异步操作的成功*/){
        resolve(value)
      } else {
        reject(error)
      }
    });
    p.then(function(){
    }).then(function(){
    }).then(function(){
    }).catch(function(e){
      // failure
    })
    

    这种连续的调用返回promise实例的情况,而且我们要兼容then方法里返回的不是promise对象,这要求对then优化,加入一个解析promise的方法resolvePromise
    三种情况:

    • 返回值是promise实例
    • 返回值是一个thenable对象或者函数
    • 没有返回值或者只返回一个普通值
    const thenable = {
      // 具有then属性,而且属性值是如下格式的函数的对象  
    then
    }
    

    相关文章

      网友评论

        本文标题:Promise内部实现的原理

        本文链接:https://www.haomeiwen.com/subject/mnpgxftx.html