
在React中处理多并发请求并实现同步处理(如等待所有请求完成后再执行后续操作)是常见需求。以下是一个通用的多并发请求同步处理封装方案,结合React的useEffect和Promise特性实现:
/**
* 同步处理多个并发请求
* @param {Array<() => Promise>} requestList - 请求函数数组(每个函数返回Promise)
* @param {Function} onSuccess - 所有请求成功后的回调(参数:所有请求结果数组)
* @param {Function} onError - 任何一个请求失败后的回调(参数:错误信息)
* @param {boolean} immediate - 是否立即执行(默认true)
* @returns {() => void} - 手动执行请求的函数
*/
const useConcurrentRequests = (
requestList,
onSuccess,
onError,
immediate = true
) => {
// 执行所有请求的函数
const executeRequests = async () => {
try {
// 使用Promise.all并发执行所有请求,等待全部完成
const results = await Promise.all(requestList.map(req => req()));
onSuccess?.(results); // 所有请求成功后回调
} catch (error) {
onError?.(error); // 任何一个请求失败则触发错误回调
}
};
// 立即执行(根据immediate控制)
React.useEffect(() => {
if (immediate) {
executeRequests();
}
}, [immediate]); // 依赖项:仅immediate变化时重新执行
return { executeRequests };
};import React, { useState } from 'react';
import axios from 'axios'; // 假设使用axios发送请求
const MyComponent = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const [error, setError] = useState(null);
// 1. 定义单个请求函数(返回Promise)
const request1 = () => axios.get('/api/data1');
const request2 = () => axios.get('/api/data2');
const request3 = () => axios.get('/api/data3');
// 2. 处理所有请求成功的回调
const handleSuccess = (results) => {
setLoading(false);
// results是所有请求的响应数组,按请求顺序排列
setData({
data1: results[0].data,
data2: results[1].data,
data3: results[2].data,
});
};
// 3. 处理请求失败的回调
const handleError = (err) => {
setLoading(false);
setError(err.message || '请求失败');
};
// 4. 使用封装的钩子:传入请求列表和回调
const { executeRequests } = useConcurrentRequests(
[request1, request2, request3], // 请求函数数组
handleSuccess, // 成功回调
handleError, // 失败回调
false // 不立即执行(手动触发)
);
// 手动触发请求
const handleFetch = () => {
setLoading(true);
setError(null);
executeRequests();
};
return (
<div>
<button onClick={handleFetch} disabled={loading}>
{loading ? '加载中...' : '获取数据'}
</button>
{error && <div style={{ color: 'red' }}>{error}</div>}
{data && (
<div>
<p>数据1: {JSON.stringify(data.data1)}</p>
<p>数据2: {JSON.stringify(data.data2)}</p>
<p>数据3: {JSON.stringify(data.data3)}</p>
</div>
)}
</div>
);
};
export default MyComponent;如果需要等待所有请求完成(包括失败的),而不是一个失败就整体失败,可以使用Promise.allSettled替代Promise.all,修改核心函数如下:
// 改为使用Promise.allSettled(等待所有请求完成,无论成功失败)
const executeRequests = async () => {
try {
const results = await Promise.allSettled(requestList.map(req => req()));
// 处理结果:区分成功和失败
const successResults = [];
const errorResults = [];
results.forEach(result => {
if (result.status === 'fulfilled') {
successResults.push(result.value);
} else {
errorResults.push(result.reason);
}
});
onSuccess?.(successResults, errorResults); // 同时返回成功和失败结果
} catch (error) {
onError?.(error);
}
};Promise.all(或allSettled)实现请求并发,提高效率immediate参数控制)all或allSettled)这种封装方式适用于需要依赖多个接口数据的场景(如页面初始化加载多个独立数据、表单提交前的多接口验证等),结合React的状态管理可清晰处理加载、成功、失败三种状态。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。