美文网首页
完整版实现Promise

完整版实现Promise

作者: 泉泉泉泉泉泉 | 来源:发表于2019-06-24 14:12 被阅读0次
/**
 * 实现一个Promise
*/
function Promise(task) {
  //接收一个处理函数
  let that = this;//缓存this
  //promise有三种状态  默认为pending
  that.status = 'pending';
  that.onFulfilledFns = [];//所有成功的回调
  that.onRejectedFns = [];//所有失败的回调
  that.value = undefined;
  function resolve(value) {
    if (that.status == 'pending') {
      that.status = 'fulfilled';
      that.value = value;
      that.onFulfilledFns.forEach(item => item(value));
    }
  };
  function reject(reason) {
    if (that.status == 'pending') {
      that.status = 'rejected';
      that.value = reason;
      that.onRejectedFns.forEach(item => item(reason));
    }
  };
  //立即执行传入的处理函数
  try {
    task(resolve, reject);
  } catch (err) {
    reject(err)
  }
};
function resolvePromise(promise2, x, resolve, reject) {
  let then;
  if (promise2 === x) {
    return reject(new Error('循环引用'));
  }
  if (x instanceof Promise) {
    //判断x的prototype所指向的对象是否存在Promise的原型链上
    if (x.status = 'pending') {
      x.then(function (y) {
        //递归 调用
        resolvePromise(promise2, y, resolve, reject);
      }, reject)
    } else if (x.status == 'fulfilled') {
      resolve(x.value);
    } else if (x.status == 'rejected') {
      reject(x.value);
    }
  } else if (x != null && typeof x == 'object' || typeof x == 'function') {
    try {
      then = x.then;
      if (typeof then == 'function') {
        then.call(x, function (y) {
          resolvePromise(promise2, y, resolve, reject);
        }, function (y) {
          reject(y)
        });
      }
    } catch (e) {
      reject(e);
    }
  } else {
    resolve(x);
  }
}
//then方法
Promise.prototype.then = function (onFulfilled, onRejected) {
  //假如没有传入异步处理程序则直接返回结果
  onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) {
    return value;
  };
  onRejected = typeof onRejected == 'function' ? onRejected : function (reason) {
    return reason;
  };
  var promise2;//用来实现链式调用
  let that = this;
  if (that.status == 'fulfilled') {
    promise2 = new Promise(function (resolve, reject) {
      let x = onFulfilled(that.value);
      resolvePromise(promise2, x, resolve, reject);
    });
  } else if (that.status == 'rejected') {
    promise2 = new Promise(function (resolve, reject) {
      let x = onRejected(that.value);
      reject(x);
    });
  } else if (that.status == 'pending') {
    promise2 = new Promise(function (resolve, reject) {
      that.onFulfilledFns.push(function () {
        let x = onFulfilled(that.value);
        resolve(x);
      });
      that.onRejectedFns.push(function () {
        let x = onRejected(that.value);
        reject(x);
      });
    });
  } else {
    promise2 = new Promise(function (resolve, reject) {
      reject('Promise内部状态错误');
    });
  }
  return promise2;
};
Promise.resolve = function (val) {
  return new Promise(function (resolve, reject) {
    resolve(val);
  });
};
Promise.reject = function (val) {
  return new Promise(function (resolve, reject) {
    reject(val);
  });
};
Promise.all = function (arrs) {
  //all方法接收一个promise数组,数组中所有异步操作结束后返回一个新的promise
  if (typeof arrs == 'object' && arrs.length > 0) {
    return new Promise(function (resolve, reject) {
      let result = [];//新的promise返回结果
      let indexNum = 0;//当前完成几个
      let resolved = function (index) {
        return function (data) {
          result[index] = data;
          indexNum++;
          if (indexNum == arrs.length) {
            resolve(result);
          }
        }
      };
      for (let i = 0; i < arrs[i].length; i++)
        arrs[i].then(resolved(i), function (reason) {
          reject(reason);
        });
    });
  } else {
    return new Promise(function (resolve, reject) {
      reject(new Error('all方法传入参数错误'));
    });
  }
};
Promise.race = function (arrs) {
  if (typeof arrs == 'object' && arrs.length > 0) {
    return new Promise(function (resolve, reject) {
      for (let i = 0; i < arrs[i].length; i++)
        arrs[i].then(function (data) {
          resolve(data);
        }, function (err) {
          reject(err);
        });
    });
  } else {
    return new Promise(function (resolve, reject) {
      reject(new Error('race方法传入参数错误'));
    })
  };
};

//test
var promise = new Promise((resolve, reject) => {
  resolve(123)
})

promise.then((res) => {
  console.log(res + 100);
  return res + 100;
}).then((res) => {
  console.log(res)
})

promise的三个缺点
1,无法取消promise,一旦新建它就会立即执行,无法中途取消
2,如果不设置回调函数,promise 内部抛出的错误,不会反映到外部
3,当处于 pending 状态时,无法得知目前进展到了哪一个阶段,是刚刚开始还是即将完成

另一个版本的Promise(推荐)

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(executor) {
  let self = this
  // 初始化
  self.status = PENDING
  // 定义回调
  self.onResolvedCallbacks = []
  self.onRejectedCallbacks = []

  function resolve(value) {
    if (value != null && value.then && typeof value.then === 'function') {
      return value.then(resolve, reject)
    }
    // 如果是初始状态.则改变成成功状态
    setTimeout(() => {
      if (self.status === PENDING) {
        self.status = FULFILLED
        self.value = value
        // 调用所有的成功
        self.onResolvedCallbacks.forEach(cb => cb(self.value))
      }
    })
  }

  function reject(reason) {
    setTimeout(() => {
      if (self.status === PENDING) {
        self.status = REJECTED
        self.value = reason
        self.onRejectedCallbacks.forEach(cb => cb(self.value))
      }
    })
  }
  try {
    // 捕获函数执行时出现的异常
    executor(resolve, reject)
  } catch(e) {
    reject(e)
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('循环引用'))
  }
  let called = false
  if (x instanceof Promise) {
    if (x.status === PENDING) {
      x.then(function(y){
        resolvePromise(promise2, y, resolve, reject)
      }, reject)
    } else {
      x.then(resolve, reject)
    }
  } else if(x != null && ((typeof x === 'object') || (typeof x.then === 'function'))) {
    // 兼容性处理
    consoole.log('兼容性处理')
    try {
      let then = x.then
      if (typeof then === 'function') {
        then.call(x, (y) => {
          if (called) return
          called = true
          resolvePromise(promise2, y, resolve, reject)
        }, (err) => {
          if (called) return
          called = true
          reject(err)
        })
      } else {
        resolve(x)
      }
    } catch(e) {
      if (called) return
      called = true
      reject(e)
    }
  } else {
    // x是一个普通的值
    resolve(x)
  }
}

Promise.prototype.then = function(onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value) {return value}
  onRejected = typeof onRejected === 'function' ? onRejected : function(reason) {throw reason}
  let self = this
  let promise2
  if (self.status == FULFILLED) {
    return  promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        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((resolve, reject) => {
      setTimeout(() => {
        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);
          }
      });
    });
   }
}

Promise.prototype.catch = function(onRejected) {
  this.then(null, onRejected)
}

Promise.race = function(promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(resolve, reject)
    }
  })
}

Promise.deferred = Promise.defer = function(){
  let defer = {};
  defer.promise = new Promise((resolve,reject) => {
    defer.resolve = resolve;
    defer.reject = reject;
  });
  return defer;
}
Promise.resolve = function (value) {
  return new Promise((resolve, reject) => resolve(value))
}
Promise.reject = function (reason) {
  return new Promise((resolve, reject) => reject(reason))
}

Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    let done = gen(promises.length, resolve)
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(val => {
        done(i, val)
      }, reject)
    }
  })
}

function gen(i, val) {
  let count = 0, result = []
  return function (i, val) {
    result[i] = val
    if (++count === i) {
      resolve(result)
    }
  }
}
module.exports = Promise

相关文章

网友评论

      本文标题:完整版实现Promise

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