函数版promise尝试

49 阅读1分钟

``

function promise(task) {
  // 判断类型函数
  const Type = (value) => {
    const match = Object.prototype.toString.call(value).match(/(\w+)/g)
      return match[1].toLocaleLowerCase()
  }
  let result = null  //  单个任务
  let asyncTask = {}  //  异步函数保存,触发resolve reject 之后调用
  let taskList  //  存放参数为数组时完成的任务
  let firstTask  //  第一个reesolve
  let hasReject = false  //  出现reject
  let firstFn
  let resolveCount = 0
  const resolve = (res, index = null) => {
    resolveCount ++
    if(hasReject) return
    result = res
    if(!firstTask) {
      firstTask = res
      firstFn && firstFn(firstTask)
    }
    if(taskList) {
      taskList[index] = res
    }
    if(asyncTask.then) {
      if (taskList && resolveCount === task.length){
        asyncTask.then(taskList)
      }else if(!taskList) {
        asyncTask.then(result)
      } 
    }
  }
  const reject = (res) => {
    result = res
    hasReject = true
    if(asyncTask) {
      asyncTask.reject(result)
    }
  }
  const then = (fn) => {
    if(hasReject) return 
    if(result) {
      fn(result)
    }else {
      asyncTask['then'] = fn
    }
  }
  const catchR = (fn) => {
    if(result) {
      fn(result)
    }else {
      asyncTask['reject'] = fn
    }
  }
  const first = (fn) => {
    firstFn = fn
  }
  if(Type(task) === 'array') {
    taskList = []
    task.forEach((fn, index) => {
      //  保存调用顺序, 按顺序返回
      fn((res) => {
        resolve(res, index)
      }, reject)
    })
  }else if (Type(task) === 'function') {
    task(resolve, reject)
  }
  return {
    then,
    catchR,
    first
  }
}
        const Type = (value) => {
          const match = Object.prototype.toString.call(value).match(/(\w+)/g)
          return match[1].toLocaleLowerCase()
        }
        //  功能测试
        let time1 = (resolve, reject) => {
          setTimeout(() => {
            reject('first')
          }, 1000);
        }
        let time2 = (resolve, reject) => {
          setTimeout(() => {
            resolve('second')
          }, 2000);}
        let time3 = (resolve, reject) => {
          setTimeout(() => {
            resolve('third')
          }, 3000);
        }
        let Fp = promise([ time3, time2, time1])
        Fp.then(res => {
          console.log(res)
        })