不用说,肯定又是面试没写出来,我太fw了

思路

Promise.all 接收一个 Promise 实例的数组或具有 Iterator 接口的对象作为参数,这个方法返回一个新的 promise 对象

实现步骤:

  1. 首先我们能知道的是,Promise.all 返回一个Promise对象
  2. 定义一个counter计数传入的数组执行情况,resolve了就+1
  3. 定义一个result数组接收 resolve 传入的参数
  4. 循环遍历传入的数组,并用Promise.resolve( )包裹:
    1. 如果数组内不是promise对象,则也不会有影响,可以正常返回一个promise对象
    2. 如果数组内是promise对象,则链式调用,也不会有影响
  5. 传入数组参数所有回调成功才是成功,返回值数组与参数顺序一致
  6. 参数数组其中一个失败,则触发失败状态,第一个触发失败的 Promise 错误信息作为 Promise.all 的错误信息。
  1. function promiseAll(promises) {
  2. return new Promise((resolve, reject) => {
  3. if (!Array.isArray(promises)) {
  4. throw new TypeError(`argument must be a array`)
  5. }
  6. let promiseNum = promises.length
  7. let resolveCount = 0
  8. let resolveResult = []
  9. for (let i = 0; i < promiseNum; i++) {
  10. //promises[i] 可能是普通值,不是promise对象
  11. Promise.resolve(promises[i]).then(value => {
  12. resolveCount++
  13. resolveResult[i] = value
  14. if (resolveCount === promiseNum) {
  15. return resolve(resolveResult)
  16. }
  17. }, error => {
  18. return reject(error)
  19. })
  20. }
  21. })
  22. }
  23. // test
  24. let p1 = new Promise(function (resolve, reject) {
  25. setTimeout(function () {
  26. resolve(1)
  27. }, 1000)
  28. })
  29. let p2 = new Promise(function (resolve, reject) {
  30. setTimeout(function () {
  31. resolve(2)
  32. }, 2000)
  33. })
  34. let p3 = new Promise(function (resolve, reject) {
  35. setTimeout(function () {
  36. resolve(3)
  37. }, 3000)
  38. })
  39. promiseAll([p3, p1, p2]).then(res => {
  40. console.log(res) // [3, 1, 2]
  41. })