手动实现一个promise 及all 等api功能

const PENDING = 'pending'
const RESOLVE = 'resolve'
const REJECTED = 'rejected'
class myPromise {
  constructor(fn) {
    // try catch 容错处理
    try {
      fn(this.resolve, this.rejected)
    } catch (error) {
      this.rejected(error)
    }
  }
//static myPromise状态
// value 成功回调的值
// fail 失败回调的值
  static = PENDING
  value = null
  fail = null
  successCallback = []
  failCallback = []
// 成功的回调
resolve = (value) => {
  if (this.static === PENDING) {
    this.static = RESOLVE
    this.value = value
    // console.log('success回调', value)
    // 这里处理多次调用then
    while (this.successCallback.length > 0) this.successCallback.shift()()
  }
}
// 失败的回调
rejected = (fail) => {
  if (this.static === PENDING) {
    this.static = REJECTED
    this.fail = fail
    // console.log('fail回调', value)
    // 这里处理多次调用then
    while (this.failCallback.length > 0) this.failCallback.shift()()
  }
}
then (successCallback, failCallback) {
  // 链式调用需返回一个新promise
  // 这里的resolve rejected是为下一个then服务的
  let promise2 = new myPromise((resolve, rejected) => {
    if (this.static === RESOLVE) {
      setTimeout(() => {
        try {
          let x = successCallback(this.value)
          // resolve(x) 只能处理常量返回值
          handleFn(promise2, x, resolve, rejected)
        } catch (error) {
          rejected(error)
        }
     }, 0)
           else if (this.static === REJECTED) {
        setTimeout(() => {
            try {
              let x = failCallback(this.fail)
              // resolve(x) 只能处理常量返回值
              handleFn(promise2, x, resolve, rejected)
            } catch (error) {
                rejected(error)
             }
        }, 0)
    } else {
        this.successCallback.push(() => {
            setTimeout(() => {
                try {
                  let x = successCallback(this.value)
                  // resolve(x) 只能处理常量返回值
                  handleFn(promise2, x, resolve, rejected)
                } catch (error) {
                  rejected(error)
                }
           }, 0)
        })
        this.failCallback.push(() => {
            setTimeout(() => {
                try {
                  let x = failCallback(this.fail)
                  // resolve(x) 只能处理常量返回值
                  handleFn(promise2, x, resolve, rejected)
                } catch (error) {
                  rejected(error)
                }
             }, 0)
        })
      }
    })
    return promise2
}
finally (callback) {
   return this.then(value => {
       return myPromise.resolve(callback()).then(() => value);
     }, reason => {
       return myPromise.resolve(callback()).then(() => { throw reason })
     })
}
  catch (failCallback) {
    return this.then(undefined, failCallback)
  }
static all (array) {
  let result = [];
  let index = 0;
  // index 用于计量是否都执行完了
  return new myPromise((resolve, reject) => {
    function addData (key, value) {
      result[key] = value;
      index++;
      if (index === array.length) {
        resolve(result);
      }
  }
for (let i = 0; i < array.length; i++) {
  let current = array[i];
  if (current instanceof myPromise) {
  // promise类型的
    current.then(value => addData(i, value), reason => reject(reason))
  } else {
  //常量
    addData(i, array[i]);
  }
  }
})
}
static resolve (value) {
// 判断是都是myPromise的实例
  if (value instanceof myPromise) return value;
// 若是普通值
  return new myPromise(resolve => resolve(value));
}
}
// 用于处理then return的是promise类型的数据 及判断是否进行了自调的错误操作
// instanceof用于判断是否是其的实例
function handleFn (promise2, x, resolve, rejected) {
  if (promise2 === x) {
    return rejected(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof myPromise) {
  x.then(resolve, rejected)
} else {
// 如果是常量直接返回
  resolve(x)
}
}
posted @ 2022-02-25 10:03  有肌肉的小眼睛  阅读(32)  评论(0)    收藏  举报