前端开发攻略---手写Promise.all(),看这篇就够了。

 

目录

1、演示

2、Promise.all介绍

3、接收的参数

4、代码

代码解析:


1、演示

2、Promise.all介绍

Promise.all 是一个用于并行执行多个 Promise 实例的方法。它接受一个包含多个 Promise 实例的数组作为参数,并返回一个新的 Promise 实例。这个新的 Promise 实例在数组中所有的 Promise 实例都成功执行后才会被成功执行,如果有任何一个 Promise 实例失败,则整个 Promise.all 实例会立刻失败。

使用 Promise.all 可以在需要同时执行多个异步操作的情况下,等待它们全部完成后再执行接下来的操作。这种方法可以提高性能,因为多个任务可以同时执行,并且可以在最短的时间内获取结果。

例如,假设有三个异步操作 A、B、C,我们可以这样使用 Promise.all 来同时执行它们:

Promise.all([A(), B(), C()])
  .then((results) => {
    // 当 A、B、C 都成功执行后,这里会获取到它们的结果数组 results
  })
  .catch((error) => {
    // 如果任何一个 Promise 实例失败,这里会捕获到错误
  });

需要注意的是,Promise.all 不会按顺序执行 Promise 实例,而是并行执行它们。因此,如果有多个 Promise 实例之间存在依赖关系,需要谨慎使用 Promise.all

3、接收的参数

Promise.all 方法实际上接受一个可迭代对象作为参数,而不一定是数组。这个可迭代对象可以是数组、类数组对象(比如 arguments 对象)、字符串、Set、Map 等具有迭代器的对象。在使用时,Promise.all 会将可迭代对象转换为一个数组,然后对该数组中的每个元素进行处理,并返回一个新的 Promise 实例。因此,您可以使用不同类型的可迭代对象作为参数来调用 Promise.all

4、代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    Promise.myAll = function (proms) {
      let res = null
      let rej = null
      const p = new Promise((resolve, reject) => {
        res = resolve
        rej = reject
      })
      let i = 0
      let fulfilled = 0
      const result = []
      for (const prom of proms) {
        const index = i
        i++
        Promise.resolve(prom).then(data => {
          result[index] = data
          fulfilled++
          if (fulfilled === i) {
            res(result)
          }
        }, rej)
      }
      if (i == 0) {
        res([])
      }
      return p
    }

    Promise.myAll([1, 2, 3, Promise.reject(123)]).then(
      res => {
        console.log(res)
      },
      err => {
        console.log(err)
      }
    )
  </script>
</html>

代码解析:

  1. 定义了一个名为Promise.myAll的静态方法,接受一个参数proms,该参数为一个包含多个Promise对象的数组。
  2. 创建了一个新的Promise对象p,并定义了两个回调函数res和rej。
  3. 使用for循环遍历proms数组中的每一个Promise对象。
  4. 对每一个Promise对象调用Promise.resolve方法将其转换为Promise对象,并通过.then方法添加对应的处理函数。
  5. 在每一个Promise对象被resolved时,将其返回的数据存储在result数组中,并增加fulfilled计数器。
  6. 当所有的Promise对象都被resolved时,调用res函数将result数组作为参数传递给新Promise对象p的resolve方法。
  7. 如果proms数组为空,则直接调用res函数将空数组作为参数传递给新Promise对象p的resolve方法。
  8. 返回新Promise对象p。
  9. 整个函数的作用是同时处理多个Promise对象,等所有Promise对象都resolved后返回一个包含所有Promise对象返回数据的数组。
  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 可以使用以下代码手写一个 `Promise.all` 函数: ``` function PromiseAll(promises) { return new Promise((resolve, reject) => { if (!Array.isArray(promises)) { return reject(new TypeError('Promise.all requires an array')); } const results = []; let remaining = promises.length; function resolver(index) { return value => { resolveAll(index, value); }; } function rejecter(reason) { reject(reason); } function resolveAll(index, value) { results[index] = value; if (--remaining === 0) { resolve(results); } } for (let i = 0; i < promises.length; i++) { Promise.resolve(promises[i]).then(resolver(i), rejecter); } }); } ``` 该函数接受一个包含多个 Promise 实例的数组,并返回一个新的 Promise 实例。如果传入的不是一个数组,则返回一个 reject 状态的 Promise 实例,并将一个 TypeError 作为原因。 如果传入的数组中的所有 Promise 都是 fulfilled 状态,则返回的 Promise 实例也是 fulfilled 状态,并将所有 Promise 的返回值作为一个数组传递给它的回调函数。如果传入的数组中至少有一个 Promise 是 rejected 状态,则返回的 Promise 实例也是 rejected 状态,并将第一个被 reject 的 Promise 的原因作为参数传递给它的回调函数。 你可以像使用标准的 `Promise.all` 函数一样使用这个函数。例如: ``` PromiseAll([promise1, promise2, promise3]).then(values => { console.log(values); // [value1, value2, value3] }).catch(reason => { console.error(reason); }); ``` 希望这对你有帮助! ### 回答2: Promise.all是JavaScript中的一个方法,用于将多个Promise对象封装为一个新的Promise对象。当所有的Promise状态都变为resolved时,返回的Promise才会变为resolved状态;如果有任意一个Promise被rejected,返回的Promise就会变为rejected状态。 下面是一个手写Promise.all的简单实现: ```javascript function myPromiseAll(promises) { return new Promise((resolve, reject) => { // 传入的参数不是数组或者为空,则直接返回resolved状态的Promise if (!Array.isArray(promises) || promises.length === 0) { return resolve([]); } let count = 0; const resultArray = []; for (let i = 0; i < promises.length; i++) { Promise.resolve(promises[i]) .then((result) => { resultArray[i] = result; count++; // 当所有Promise都变成resolved状态时,返回结果数组 if (count === promises.length) { resolve(resultArray); } }) .catch(reject); // 有任意一个Promise被rejected,则返回rejected状态的Promise } }); } ``` 这个手写Promise.all方法接受一个Promise数组作为参数。首先判断传入的参数是否为一个数组,若不是数组或为空,则直接返回一个resolved状态的Promise,并将结果数组设置为空数组。 接着,定义一个计数器count,用于记录已经变为resolved状态的Promise的数目。同时创建一个空数组resultArray,用于存储每个Promise的结果。 使用for循环遍历传入的Promise数组,调用Promise.resolve方法将每个Promise对象转换为Promise类型,以确保每个元素都是一个Promise对象。 在每个Promise对象上调用then方法,当其状态变为resolved时,将结果存入resultArray数组,并将计数器加1。当所有的Promise都变为resolved状态时,通过调用resolve方法返回结果数组。 如果有任意一个Promise被rejected,就会调用catch方法,并将错误信息传给reject方法,返回一个rejected状态的Promise。 这个手写Promise.all实现了基本的功能,用于同时处理多个Promise对象,并可以根据情况返回resolved或rejected状态的Promise。 ### 回答3: Promise.all是一个用于并行执行多个promise的方法,当所有的promise都变为resolved状态时,它才会变为resolved状态,并返回一个包含所有promise结果的数组;如果其中一个promise变为rejected状态,那么Promise.all也会变为rejected状态,并返回第一个被rejected的promise的错误信息。 下面是一个简单的手写Promise.all的示例: ```javascript function myPromiseAll(promises) { return new Promise((resolve, reject) => { const results = []; let count = 0; for (let i = 0; i < promises.length; i++) { promises[i].then((result) => { results[i] = result; count++; if (count === promises.length) { resolve(results); } }).catch((error) => { reject(error); }); } }); } ``` 这个手写Promise.all接受一个包含多个promise的数组作为参数,通过循环遍历每一个promise,使用then方法处理其resolved状态的情况,将结果保存到results数组中,并通过计数器count来判断是否所有的promise都已完成。当所有的promise都完成时,调用resolve方法将结果传递给外部;如果有任何一个promise被rejected,通过catch方法捕捉错误并调用reject方法将错误信息传递给外部。 这只是一个简单的手写Promise.all示例,实际上,Promise.all还有很多其他的功能和细节需要考虑,例如处理空数组或非promise值的情况,以及对结果顺序的保持等,但以上代码可以作为一个基本的示例来理解Promise.all的工作原理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bbamx.

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值