Reactjs 反应-旧承诺覆盖新结果

Reactjs 反应-旧承诺覆盖新结果,reactjs,promise,es6-promise,Reactjs,Promise,Es6 Promise,我有一个问题,我很确定我不是唯一一个有这个问题的人。。。虽然我试图找到一个解决办法,但我并没有真正找到符合我目的的东西 我不会发布太多的代码,因为这不是一个真正的代码问题,而是一个逻辑问题 假设我有以下的钩子: useEffect(() => { fetchFromApi(props.match.params.id); }, [props.match.params.id]); 假设fetchFromApi的结果显示在UI中的一个简单表中 现在,假设用户单击导航中的一个实体,那么浏

我有一个问题,我很确定我不是唯一一个有这个问题的人。。。虽然我试图找到一个解决办法,但我并没有真正找到符合我目的的东西

我不会发布太多的代码,因为这不是一个真正的代码问题,而是一个逻辑问题

假设我有以下的钩子:

useEffect(() => {
    fetchFromApi(props.match.params.id);
}, [props.match.params.id]);
假设fetchFromApi的结果显示在UI中的一个简单表中

现在,假设用户单击导航中的一个实体,那么浏览器URL中的ID属性将发生变化,效果将触发,从而导致API调用。假设使用此特定ID的呼叫需要5秒钟

在这5秒钟内,用户再次单击导航中的一个元素,因此钩子再次触发。这一次,API调用只需要0,1秒。结果立即显示出来

但第一个呼叫仍在运行。一旦完成,它将覆盖当前结果,从而导致错误的导航部分显示错误的数据

有没有简单的方法来解决这个问题?我知道我不能默认取消承诺,但我也知道有办法实现它

另外,fetchFromApi可能不是单个API调用,而是对多个端点的多个调用,因此整个过程可能会变得非常棘手


谢谢你的帮助

解决这个问题的方法非常简单,您只需确定您得到的响应是否来自最新的API调用,然后就可以了。您可以通过将triggerTime存储在ref中来实现。如果API调用在另一次触发,ref将存储不同的值,但是闭包变量将保留相同的先前设置值,这意味着在此之后又触发了另一个API调用,因此我们不需要接受当前结果

const timer = useRef(null);
useEffect(() => {
    fetchFromApi(props.match.params.id, timer);
}, [props.match.params.id]);

function fetchFromApi(id, timer) {
     timer.current = Date.now();
     const triggerTime = timer.current;
     fetch('path').then(() => {
         if(timer.current == triggerTime) {
              // process result here
              // accept response and update state
         }
     })

} 

处理此类场景的其他方法可以取消以前挂起的API请求。如果您使用
Axios
它为您提供了可以使用的cancelToken,同样,您也可以取消XMLHttpRequests。

因为您正在调用后端,我会禁用页面并显示加载框,直到结果显示出来retrieved@FortyTwo我已经在做这个了。。。但这并不能解决承诺“无效”时解决的问题,因为已经显示了一个更新的承诺,该承诺解决得更快。您是否使用相同的数据结构来存储来自两个端点的数据?@UmairSarfraz始终是同一个端点,只是另一个筛选器ID。您尝试过吗?