面试题答案
一键面试实现思路
- 队列管理:使用一个队列来存储所有异步操作的结果。只有当队列中的所有操作都完成后,才一次性更新
State
。这样可以避免部分异步操作先完成导致State
不一致。 - 状态标记:为每个异步操作添加一个状态标记,如
pending
、resolved
、rejected
,以便跟踪操作的进展。 - 集中处理:通过一个集中的函数来处理所有异步操作的结果,确保
State
更新的一致性。
关键代码框架
import React, { useState, useEffect } from 'react';
// 模拟异步API调用
const apiCall1 = () => new Promise((resolve) => setTimeout(() => resolve('Result 1'), 1000));
const apiCall2 = () => new Promise((resolve) => setTimeout(() => resolve('Result 2'), 1500));
const MyComponent = () => {
const [state, setState] = useState({
data1: null,
data2: null,
status: 'pending'
});
useEffect(() => {
const queue = [];
const updateState = () => {
if (queue.every(result => result.status ==='resolved')) {
const newState = {};
queue.forEach(result => {
if (result.key === 'data1') newState.data1 = result.value;
if (result.key === 'data2') newState.data2 = result.value;
});
setState({...newState, status:'resolved' });
}
};
const addToQueue = (key, promise) => {
const operation = { key, status: 'pending' };
queue.push(operation);
promise.then(value => {
operation.status ='resolved';
operation.value = value;
updateState();
}).catch(error => {
operation.status ='rejected';
operation.error = error;
// 可以选择处理错误,这里简单打印
console.error(`Error in ${key}:`, error);
});
};
addToQueue('data1', apiCall1());
addToQueue('data2', apiCall2());
}, []);
return (
<div>
{state.status === 'pending' && <p>Loading...</p>}
{state.status ==='resolved' && (
<div>
<p>Data 1: {state.data1}</p>
<p>Data 2: {state.data2}</p>
</div>
)}
</div>
);
};
export default MyComponent;
在上述代码中:
useEffect
钩子在组件挂载时触发,初始化异步操作队列。addToQueue
函数将每个异步操作及其结果添加到队列,并在操作完成时更新队列状态。updateState
函数在所有操作都完成时,统一更新State
,确保一致性。