美文网首页前端大全
原生JS模拟Promise实现详解

原生JS模拟Promise实现详解

作者: yun_154192 | 来源:发表于2019-03-11 10:59 被阅读79次

    作为一名程序猿,经常遇到回调函数的情况,原生js的回调函数是一层一层的嵌套调用,而es6提供了一种新的写法,Promise,它可以把原本的嵌套回调函数实现成横向的调用,即链式调用。
    下面看一个Promise的简单用法:

    //Promise函数接受一个函数作为参数,接受的函数中的resolve和reject分别作为执行成功和执行失败的函数
    var promise = new Promise(function(resolve, reject){
      if(/*异步执行成功*/){
        resolve()
      }else{
        reject()  
      }
    })
    //通过then设置之后的两个操作
    .then(function(){
      //回调执行成功的操作
    },function(){
      //回调执行失败的操作
    })
    

    接着开始模拟:

    (一)模拟模拟Promise构造函数

    function _Promise(resolver){
      this._status = 'pending'
      this._result = ''
      resolver(this.resolve.bind(this), this.reject.bind(this))
    }
    

    首先,_Promise构造函数会接收一个函数resolver并执行,函数中又包含resolve和reject两个参数,然后,_Promise构造函数生成的实例有三种状态,分别是pending(初始值)、fullfilled(成功)和rejected(失败),且由pending变为成功或者失败后状态不可逆。

    (二)实现resolve和reject函数

    _Promise.prortotype.resolve = function(result){
      if(this._status === 'pending'){
        this._status = 'fullfilled'
        this._result = result
      }
    }
    _Promise.prototype.reject = function(result){
      if(this._status === 'pending'){
        this._status = 'rejected'
        this._result = result
      }
    }
    

    resolve和reject函数执行的时候会先判断状态,如果是pending则执行,且将状态变为fullfilled或者rejected,并将resolve/reject函数中参数传递给_result,以便then函数调用时使用。

    (三)模拟then函数

    _Promise.prototype.then = function(isResolve, isReject){
      if(this._status === 'fullfilled'){
        var _isPromise = isResolve(this._result)  //执行成功函数
        if(_isPromise instanceof _Promise){  //如果执行成功函数后返回的是_Promise实例,则返回这个实例
          return _Promise
        }
        return this
      }else if(this._status === 'rejected' && arguments[1]){  //只有状态是失败且有第二个参数才执行
        var err = new TypeError(this._result)
        var _isPromise = isReject(err)  //将错误信息传递给失败函数
        if(_isPromise instanceof _Promise){  //如果执行失败函数后返回的是_Promise实例,则返回这个实例
          return _Promise
        }
        return this
      } 
    }
    

    因为有可能存在链式调用,所以执行then函数的返回值需要判断,如果isResolve或者isReject函数返回的是一个新的_Promise实例,则返回这个实例,否则返回当前实例

    (四)模拟catch函数

    //catch函数与reject函数十分类似
    _Promise.prototype.catch = function(isReject){
      if(this._status === 'rejected'){
        var _isPromise = isReject(this._result)  
        if(_isPromise instanceof _Promise){
          return _Promise
        }
        return this
      }
    }
    

    至此,Promise已经模拟完成~

    相关文章

      网友评论

        本文标题:原生JS模拟Promise实现详解

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