4

一 Promise函数

Promise函数是es6中一个比较有用的特性,一般用来处理异步操作。让你的代码中不再只有回调函数套回调函数。
promise函数的运行流程如下图:

图片描述

来看下面一个简单demo,

setTimeout(function(){
 console.log('hello')
},1000)

下面再看下promise的实现

let p1 = new Promise(function(resolve) {
   setTimeout(function(){
    resolve('hello')
},1000)
})
.then(function(resolve){
   console.log(resolve)
})

上面两种实现的话,我们可以看出,当使用promise的时候,其更能凸显出执行代码和处理结果的逻辑分离

二 简单模拟一个promise

function MyPromise (fn) {
  this._status = 'pending'
  this._value = undefined
  this._onResolvedCallback = []
  this._onRejectCallback = []
  fn(resolve.bind(this), reject.bind(this))
}
function resolve (value) {
  if (this._status === 'pending') {
    this._status = 'resolved'
    this._value = value
    var fn
    while (fn = this._onResolvedCallback.pop()) {
      fn.call(this, value)
    }
  }
}
function reject (reason) {
  if(this._status === 'pending') {
    this._status = 'reject'
    this._value = reason
    var fn
    while (fn = this._onRejectCallback.pop()) {
      fn.call(this,reason)
    }
  }
}
MyPromise.prototype.then = function (onResolved, onRejected) {
  var self = this
  var promise2
  onResolved = typeof onResolved === 'function' ? onResolved : function (v) {}
  onRejected = typeof onRejected === 'function' ? onRejected : function (r) {}
  if (self._status === 'resolved') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onResolved(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
        resolve(x)
      } catch (e) {
        reject(e)
      }
    })
  }
  if (self._status === 'rejected') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onRejected(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
      } catch(e) {
        reject(e)
      }
    })
  }
  if (self._status === 'pending') {
    return promise2 = new MyPromise (function (resolve, reject) {
      self._onResolvedCallback.push(function (value) {
        try{
          var x = onResolved(self._value)
          if (x instanceof MyPromise) {
              x.then(resolve, reject)
          }
        } catch (e) {
          reject(e)
        }
      })
      self._onRejectCallback.push(function(reason) {
        try {
          var x =onRejected(self._value)
          if(x instanceof Promise) {
            x.then(resolve, reject)
          }
          resolve(x)
        } catch (e) {
          reject(e)
        }
      })
    })
  }
}
//test code
  var myFirstPromise = new MyPromise(function(resolve, reject){
      setTimeout(function(){
          resolve("成功!"); //代码正常执行!
      }, 1000);
  });
  myFirstPromise.then(function (successMessage) {
     console.log("Yay! " + successMessage);
  })

上述是一个模拟promise基础功能的代码。主要分为三块,构造函数,resolve和reject函数,以及then函数
下面来简单说明一下这三个部分

2.1 构造函数

function MyPromise (fn) {
  this._status = 'pending'
  this._value = undefined
  this._onResolvedCallback = []
  this._onRejectCallback = []
  fn(resolve.bind(this), reject.bind(this))
}

构造函数部分,主要为promise对象声明了一个状态属性,一个值属性(传递resolve或者reject的值)还有当promise的状态为resolve或者reject时候的回调函数。

2.2 resolve部分和reject部分

function resolve (value) {
  if (this._status === 'pending') {
    this._status = 'resolved'
    this._value = value
    var fn
    while (fn = this._onResolvedCallback.pop()) {
      fn.call(this, value)
    }
  }
}
function reject (reason) {
  if(this._status === 'pending') {
    this._status = 'reject'
    this._value = reason
    var fn
    while (fn = this._onRejectCallback.pop()) {
      fn.call(this,reason)
    }
  }
}

resolve和reject函数,主要用来改变状态,用传递的值运行回调函数,

2.3 then部分

MyPromise.prototype.then = function (onResolved, onRejected) {
  var self = this
  var promise2
  onResolved = typeof onResolved === 'function' ? onResolved : function (v) {}
  onRejected = typeof onRejected === 'function' ? onRejected : function (r) {}
  if (self._status === 'resolved') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onResolved(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
        resolve(x)
      } catch (e) {
        reject(e)
      }
    })
  }
  if (self._status === 'rejected') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onRejected(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
      } catch(e) {
        reject(e)
      }
    })
  }
  if (self._status === 'pending') {
    return promise2 = new MyPromise (function (resolve, reject) {
      self._onResolvedCallback.push(function (value) {
        try{
          var x = onResolved(self._value)
          if (x instanceof MyPromise) {
              x.then(resolve, reject)
          }
        } catch (e) {
          reject(e)
        }
      })
      self._onRejectCallback.push(function(reason) {
        try {
          var x =onRejected(self._value)
          if(x instanceof Promise) {
            x.then(resolve, reject)
          }
          resolve(x)
        } catch (e) {
          reject(e)
        }
      })
    })
  }
}

then方法返回的是一个promise对象,一般是返回新的promise。then方法的逻辑主要是判断status的状态,改变状态,把处理方法添加到promise的方法属性数组里面。

三 总结

图片描述VPepb


淼淼真人
1.1k 声望202 粉丝

一个前端菜鸟!