乐趣区

关于javascript:手写promisePromiseallPromiserace

手写 promise

const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'

function MyPromise(fn) {
  // 保留初始化状态
  var self = this

  // 初始化状态
  this.state = PENDING

  // 用于保留 resolve 或者 rejected 传入的值
  this.value = null

  // 用于保留 resolve 的回调函数
  this.resolvedCallbacks = []

  // 用于保留 reject 的回调函数
  this.rejectedCallbacks = []

  // 状态转变为 resolved 办法
  function resolve(value) {
    // 判断传入元素是否为 Promise 值,如果是,则状态扭转必须期待前一个状态扭转后再进行扭转
    if (value instanceof MyPromise) {return value.then(resolve, reject)
    }

    // 保障代码的执行程序为本轮事件循环的开端
    setTimeout(() => {
      // 只有状态为 pending 时能力转变,if (self.state === PENDING) {
        // 批改状态
        self.state = RESOLVED

        // 设置传入的值
        self.value = value

        // 执行回调函数
        self.resolvedCallbacks.forEach((callback) => {callback(value)
        })
      }
    }, 0)
  }

  // 状态转变为 rejected 办法
  function reject(value) {
    // 保障代码的执行程序为本轮事件循环的开端
    setTimeout(() => {
      // 只有状态为 pending 时能力转变
      if (self.state === PENDING) {
        // 批改状态
        self.state = REJECTED

        // 设置传入的值
        self.value = value

        // 执行回调函数
        self.rejectedCallbacks.forEach((callback) => {callback(value)
        })
      }
    }, 0)
  }

  // 将两个办法传入函数执行
  try {fn(resolve, reject)
  } catch (e) {
    // 遇到谬误时,捕捉谬误,执行 reject 函数
    reject(e)
  }
}

MyPromise.prototype.then = function (onResolved, onRejected) {
  // 首先判断两个参数是否为函数类型,因为这两个参数是可选参数
  onResolved =
    typeof onResolved === 'function'
      ? onResolved
      : function (value) {return value}

  onRejected =
    typeof onRejected === 'function'
      ? onRejected
      : function (error) {throw error}

  // 如果是期待状态,则将函数退出对应列表中
  if (this.state === PENDING) {this.resolvedCallbacks.push(onResolved)
    this.rejectedCallbacks.push(onRejected)
  }

  // 如果状态曾经凝固,则间接执行对应状态的函数

  if (this.state === RESOLVED) {onResolved(this.value)
  }

  if (this.state === REJECTED) {onRejected(this.value)
  }
}

手写 Promise.all()

Promise.all = function(iterator) {if (!Array.isArray(iterator)) return;
  let count = 0;
  let res = [];
  return new Promise((resolve, reject) => {for(let item of iterator) {Promise.resolve(item)
      .then(data => {res[count++] = data;
        if (count === iterator.length) {resolve(res);
        }
      })
      .catch(e => {reject(e);
      })
    }
  })
}

// test
let p1 = Promise.resolve(3);
let p2 = 4;
let p3 = new Promise(resolve => {setTimeout(resolve, 100, 'lee')
  // setTimeout 的第三个往后参数都是用来作为第一个参数也就是函数的参数, 也就是其实是 setTimeout(resolve('lee'), 100)
});
Promise.all([p1, p2, p3]).then(data => {console.log(data);
})

手写 Promise.race()

Promise.race = function(iterator) {return new Promise((resolve, reject) => {for(let item of iterator) {Promise.resolve(item)
      .then(data => {resolve(data)
      })
      .catch(e => {reject(e)
      })
    }
  })
}

let p1 = new Promise(resolve => {setTimeout(resolve, 105, 'p1 done')
})
let p2 = new Promise(resolve => {setTimeout(resolve, 100, 'p2 done')
})
Promise.race([p1, p2]).then(data => {console.log(data); // p2 done
})
退出移动版