【发布时间】:2021-08-24 13:27:08
【问题描述】:
我必须处理非常奇怪的案件。
我们有几个盒子,我们可以在每个盒子上调用一些动作。当我们单击框内的按钮时,我们会调用服务器上的某个端点(使用axios)。来自服务器的响应返回新的更新信息(关于所有框,而不是我们调用操作的唯一框)。
问题: 如果用户非常快地单击许多框上的提交按钮,则请求会一一调用端点。它有时会导致错误,因为它在服务器上以错误的顺序计算(盒子组的状态取决于单个盒子的状态)。我知道这可能是更多的后端问题,但我必须尝试在前端解决这个问题。
提案修正:
在我看来,在这种情况下,最简单的解决方法是禁用每个 submit 按钮(如果有任何请求正在进行)。不幸的是这个解决方案很慢,项目负责人拒绝了这个提议。
我们想要达到的目标: 在某种程度上,我们希望在不禁用每个按钮的情况下对请求进行排队。目前对我来说完美的解决方案:
- 单击第一个按钮 - 调用端点,请求在服务器上挂起。
- 单击第二个按钮 - 按钮显示微调器/加载信息而不调用端点。
- 服务器让我们响应第一次点击,然后我们才真正调用第二次请求。
我认为这样的事情是巨大的反模式,但我没有设定规则。 ;)
我正在阅读例如redux-observable,但如果我不需要,我不想为redux 使用其他中间件(现在我们使用redux-thunk)。 Redux-saga 会好的,可惜我不知道这个工具。我准备了简单的codesandbox example(我在redux 操作中添加了超时以便于测试)。
我只有一个愚蠢的提案解决方案。创建数据数组需要发送正确的请求,并在 useEffect 内部检查数组长度是否等于 1。像这样:
const App = ({ boxActions, inProgress, ended }) => {
const [queue, setQueue] = useState([]);
const handleSubmit = async () => { // this code do not work correctly, only show my what I was thinking about
if (queue.length === 1) {
const [data] = queue;
await boxActions.submit(data.id, data.timeout);
setQueue(queue.filter((item) => item.id !== data.id));
};
useEffect(() => {
handleSubmit();
}, [queue])
return (
<>
<div>
{config.map((item) => (
<Box
key={item.id}
id={item.id}
timeout={item.timeout}
handleSubmit={(id, timeout) => setQueue([...queue, {id, timeout}])}
inProgress={inProgress.includes(item.id)}
ended={ended.includes(item.id)}
/>
))}
</div>
</>
);
};
有什么想法吗?
【问题讨论】:
标签: reactjs axios redux-saga redux-thunk