07-使用 JavaScript Promise 并行处理多个请求

使用 JavaScript Promise 并行处理多个请求

笔记+分享
在现代Web开发中,处理多个异步请求并行是一个常见需求。JavaScript中的Promise提供了一种强大的机制来管理这些并行操作。本文将详细介绍如何使用Promise.allPromise.allSettled来实现这一点,并提供一些实用的示例代码。

Promise.all 和 Promise.allSettled

在处理多个并行请求时,最常用的两个Promise方法是Promise.allPromise.allSettled

Promise.all

Promise.all方法接收一个Promise数组,当所有Promise都成功时,返回一个包含所有结果的数组。如果任何一个Promise失败,整个Promise.all都会立即失败,并抛出第一个失败的Promise的错误。

const promise1 = new Promise((resolve) => {
    setTimeout(() => resolve('Promise 1 resolved'), 1000);
});

const promise2 = new Promise((resolve) => {
    setTimeout(() => resolve('Promise 2 resolved'), 2000);
});

const promise3 = new Promise((_, reject) => {
    setTimeout(() => reject('Promise 3 rejected'), 1500);
});

Promise.all([promise1, promise2, promise3])
    .then(results => {
        console.log(results); // 不会执行
    })
    .catch(error => {
        console.error(error); // 输出: Promise 3 rejected
    });

在这个例子中,Promise.all因为promise3被拒绝而失败,导致整个操作被短路。

Promise.allSettled

相比之下,Promise.allSettled方法会等待所有Promise都完成,无论是成功还是失败。它返回一个包含每个Promise结果对象的数组,每个结果对象都有一个status属性(“fulfilled"或"rejected”)和相应的valuereason属性。

Promise.allSettled([promise1, promise2, promise3])
    .then(results => {
        results.forEach((result, index) => {
            if (result.status === 'fulfilled') {
                console.log(`Promise ${index + 1} fulfilled with value: ${result.value}`);
            } else {
                console.error(`Promise ${index + 1} rejected with reason: ${result.reason}`);
            }
        });
    });

在这个例子中,所有Promise的状态都会被处理,无论它们是成功还是失败。

使用 Promise.all 实现错误处理

虽然Promise.allSettled可以处理所有Promise的结果,无论它们是否成功或失败,但有时我们更希望使用Promise.all,但又不想因为某个Promise失败而导致所有Promise都被短路。为了解决这个问题,我们可以通过在每个Promise周围添加一个错误处理逻辑来实现。这可以通过在每个Promise后添加.catch来捕获错误并返回一个标记为失败的结果对象。

包装 Promise 以处理错误

我们可以创建一个包装函数,确保所有Promise都能执行,并返回一个包含结果和错误的数组。

const handlePromise = (promise) => {
    return promise
        .then(result => ({ status: 'fulfilled', value: result }))
        .catch(error => ({ status: 'rejected', reason: error }));
};

const fetchUser = fetch('https://api.example.com/user').then(res => res.json());
const fetchPosts = fetch('https://api.example.com/posts').then(res => res.json());
const fetchComments = fetch('https://api.example.com/comments').then(res => res.json());

Promise.all([
    handlePromise(fetchUser),
    handlePromise(fetchPosts),
    handlePromise(fetchComments)
])
.then(results => {
    results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
            console.log(`Request ${index + 1} succeeded with value:`, result.value);
        } else {
            console.error(`Request ${index + 1} failed with reason:`, result.reason);
        }
    });
});

详细示例

假设我们有三个并行的API请求,即使其中一个请求失败,我们仍然希望其他请求能够完成并处理它们的结果或错误。

const handlePromise = (promise) => {
    return promise
        .then(result => ({ status: 'fulfilled', value: result }))
        .catch(error => ({ status: 'rejected', reason: error }));
};

// 示例请求
const fetchUser = fetch('https://api.example.com/user').then(response => {
    if (!response.ok) {
        throw new Error('Failed to fetch user');
    }
    return response.json();
});

const fetchPosts = fetch('https://api.example.com/posts').then(response => {
    if (!response.ok) {
        throw new Error('Failed to fetch posts');
    }
    return response.json();
});

const fetchComments = fetch('https://api.example.com/comments').then(response => {
    if (!response.ok) {
        throw new Error('Failed to fetch comments');
    }
    return response.json();
});

// 使用 Promise.all 执行所有请求
Promise.all([
    handlePromise(fetchUser),
    handlePromise(fetchPosts),
    handlePromise(fetchComments)
])
.then(results => {
    results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
            console.log(`Request ${index + 1} succeeded with value:`, result.value);
        } else {
            console.error(`Request ${index + 1} failed with reason:`, result.reason);
        }
    });
});

解析

  1. handlePromise 函数:该函数接收一个Promise,并在Promise解析或拒绝时返回一个标准化的对象,包含statusvaluereason
  2. 并行请求:每个请求通过fetch方法发起,并附带错误处理。如果请求失败,抛出一个错误。
  3. Promise.all:使用Promise.all并行执行所有经过handlePromise包装的请求。即使其中一个或多个请求失败,所有请求都会继续执行。
  4. 结果处理:在then方法中,遍历所有结果,根据status属性分别处理成功和失败的请求。

总结

通过这种方式,使用Promise.all时,可以确保所有Promise都能执行,无论其中某些Promise是否失败。这在处理多个并行请求时非常有用,可以确保即使某些请求失败,也能获取其他请求的结果,从而提高代码的健壮性和可靠性。希望本文的介绍和示例代码能够帮助你更好地理解和使用JavaScript中的Promise来管理并行请求。


通过这种方式,开发者可以更灵活地处理并行请求,无论是使用Promise.all还是Promise.allSettled,都能够确保在复杂的异步操作中更加健壮地管理请求结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值