使用 Promise.all 处理多个 Promise 同时失败的情况

简介: 【10月更文挑战第26天】通过以上几种方法,我们可以根据具体的需求和环境选择合适的方式来处理多个 `Promise` 同时失败的情况,从而更好地进行错误处理和程序的稳定性保障。

Promise.all 是一个非常实用的方法,用于同时处理多个 Promise,并在所有 Promise 都成功完成时返回一个包含所有结果的数组。然而,当其中任何一个 Promise 失败时,Promise.all 会立即 reject,并且只会返回第一个失败的 Promise 的错误信息。但在实际应用中,我们可能需要获取所有失败的 Promise 的错误信息,以便更全面地了解问题所在并进行相应处理。

方法一:使用 Promise.all 结合 catch 方法

  • 这种方法是最基本的处理方式,通过在 Promise.all 后面添加 catch 方法来捕获第一个失败的 Promise 所抛出的错误。虽然这种方式只能获取到第一个失败的错误信息,但在某些情况下,如果只需要对第一个失败的情况进行处理,这种方法就足够了。示例代码如下:
    ```javascript
    const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    reject(new Error('Promise 1 failed'));
    }, 1000);
    });

const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Promise 2 failed'));
}, 500);
});

Promise.all([promise1, promise2])
.then(results => {
console.log('All promises resolved:', results);
})
.catch(error => {
console.error('First promise failed:', error);
});

在上述示例中,`promise2` 会先于 `promise1` 失败,因此 `Promise.all` 的 `catch` 方法会捕获到 `promise2` 的错误信息并打印出来。

### 方法二:使用 Promise.allSettled
- `Promise.allSettled` 是 ES2020 引入的新方法,它会等待所有的 `Promise` 都完成,无论它们是成功还是失败,并返回一个包含每个 `Promise` 状态和结果的数组。对于成功的 `Promise`,其结果对象的 `status` 属性为 `fulfilled`,`value` 属性为成功的值;对于失败的 `Promise`,其结果对象的 `status` 属性为 `rejected`,`reason` 属性为失败的原因。示例代码如下:
```javascript
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 3 resolved');
  }, 1000);
});

const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Promise 4 failed'));
  }, 500);
});

Promise.allSettled([promise3, promise4])
.then(results => {
    results.forEach(result => {
      if (result.status === 'fulfilled') {
        console.log('Promise fulfilled:', result.value);
      } else {
        console.error('Promise rejected:', result.reason);
      }
    });
  });

在这个示例中,Promise.allSettled 会等待 promise3promise4 都完成,然后分别处理它们的结果,从而可以获取到所有 Promise 的状态和相应的信息。

方法三:自定义处理函数

  • 如果不使用 Promise.allSettled(例如在不支持 ES2020 的环境中),我们可以自定义一个类似 Promise.allSettled 的函数来处理多个 Promise 同时失败的情况。以下是一个简单的示例:
    ```javascript
    function allPromisesSettled(promises) {
    const results = [];
    let completedCount = 0;

    return new Promise((resolve, reject) => {
    promises.forEach((promise, index) => {

    Promise.resolve(promise)
     .then(result => {
        results[index] = { status: 'fulfilled', value: result };
      })
     .catch(error => {
        results[index] = { status: 'rejected', reason: error };
      })
     .finally(() => {
        completedCount++;
        if (completedCount === promises.length) {
          resolve(results);
        }
      });
    

    });
    });
    }

const promise5 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 5 resolved');
}, 1000);
});

const promise6 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Promise 6 failed'));
}, 500);
});

allPromisesSettled([promise5, promise6])
.then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('Promise fulfilled:', result.value);
} else {
console.error('Promise rejected:', result.reason);
}
});
});

在这个自定义函数中,我们遍历传入的所有 `Promise`,分别处理它们的成功和失败情况,并将结果存储在一个数组中。当所有 `Promise` 都完成后,返回包含所有结果的数组,从而实现了类似 `Promise.allSettled` 的功能。

### 方法四:结合 async/await
- 当使用 `async/await` 语法时,可以更方便地处理 `Promise.all` 或自定义函数返回的结果。以下是结合上述自定义函数 `allPromisesSettled` 使用 `async/await` 的示例:
```javascript
async function handlePromises() {
  const results = await allPromisesSettled([promise5, promise6]);
  results.forEach(result => {
    if (result.status === 'fulfilled') {
      console.log('Promise fulfilled:', result.value);
    } else {
      console.error('Promise rejected:', result.reason);
    }
  });
}

handlePromises();

这种方式使代码看起来更像同步代码,提高了代码的可读性和可维护性,同时也能够方便地处理多个 Promise 的结果和错误。

通过以上几种方法,我们可以根据具体的需求和环境选择合适的方式来处理多个 Promise 同时失败的情况,从而更好地进行错误处理和程序的稳定性保障。

目录
相关文章
|
28天前
|
前端开发
`Promise.allSettled()`方法与`Promise.all()`方法有何不同?
`Promise.allSettled()` 提供了一种更灵活和全面的方式来处理多个 `Promise`,使得我们能够更好地应对各种异步操作的情况,尤其是需要详细了解每个 `Promise` 结果的场景。
|
4月前
|
前端开发
手写实现ES6的Promise.all()和Promise.race()函数
这篇文章介绍了如何手写实现ES6的`Promise.all()`和`Promise.race()`函数,提供了实现这两个Promise聚合函数的详细代码示例,并展示了如何使用它们。
手写实现ES6的Promise.all()和Promise.race()函数
|
6月前
|
JavaScript 前端开发
vue实现循环发起多个异步请求——Promise.all()与Promise.race()
vue实现循环发起多个异步请求——Promise.all()与Promise.race()
345 1
|
5月前
|
前端开发 JavaScript
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
723 0
Promise.all和Promise.race的区别和使用
比如当数组里的P1,P2都执行完成时,页面才显示。 值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P2 Promise.all成功返回成功数组, 失败返回失败数据,一但失败就不会继续往下走
|
前端开发
前端学习案例24-promise.all和promise.race之2
前端学习案例24-promise.all和promise.race之2
86 0
前端学习案例24-promise.all和promise.race之2
|
前端开发
前端学习案例23-promise.all和promise.race
前端学习案例23-promise.all和promise.race
79 0
前端学习案例23-promise.all和promise.race
|
前端开发
前端学习案例1-promise之promise.all
前端学习案例1-promise之promise.all
67 0
前端学习案例1-promise之promise.all
|
前端开发
Promise.all和promise.race的应用场景举例
Promise.all和promise.race的应用场景举例
275 0
|
前端开发 JavaScript
Promise.all等待所有Promise执行完成
Promise.all等待所有Promise执行完成
394 0
下一篇
DataWorks