Javascript 只让最后一个API调用通过

Javascript 只让最后一个API调用通过,javascript,reactjs,api,axios,Javascript,Reactjs,Api,Axios,因此,我有一个inputfield,当您在其中键入内容时,它会对我们的后端进行API调用,我遇到的问题是: 假设我们正在进行打字测试,我将对此进行4次调用: t te tes 试验 因为调用't'比'test'花费的时间要长得多,所以最后将加载来自't'的数据。这意味着我没有从“测试”中获取请求的数据 我的问题是,你有没有办法取消之前的请求?('t','te','tes')只让你最后一个电话接通?或者这只是优化API速度的性能 我已经尝试过超时半秒,但问题有时仍然存在。当您对用户输入进行异

因此,我有一个inputfield,当您在其中键入内容时,它会对我们的后端进行API调用,我遇到的问题是:

假设我们正在进行打字测试,我将对此进行4次调用:

  • t
  • te
  • tes
  • 试验
因为调用't'比'test'花费的时间要长得多,所以最后将加载来自't'的数据。这意味着我没有从“测试”中获取请求的数据

我的问题是,你有没有办法取消之前的请求?('t','te','tes')只让你最后一个电话接通?或者这只是优化API速度的性能


我已经尝试过超时半秒,但问题有时仍然存在。

当您对用户输入进行异步调用时,异步结果解析的顺序可能不是用户输入的顺序(因此不是去盎司问题)。当用户键入
s
时,您使用
s
进行异步调用,然后用户键入
e
并使用
se
进行异步调用。现在有两个异步调用未解析,一个是
s
,另一个是
se

假设
s
调用需要一秒钟,
se
调用需要10毫秒,然后
se
首先解析,UI设置为
se
的结果,但之后
s
解析,UI设置为
s
的结果。现在您的UI不一致

解决这一问题的一种方法是使用debounce,希望您永远不会得到持续时间超过debounce时间的异步调用,但无法保证。另一种方法是取消旧的请求,但这太麻烦了,无法实现,而且并非所有浏览器都支持。我在下面展示的方法只是在发出新请求时拒绝异步承诺。因此,当用户键入
s
e
请求
s
se
时,但当
s
se
之后解析时,它将被拒绝,因为它已被更新的请求替换

const REPLACED='REPLACED';
const last=(fn)=>{
const current={value:{};
返回(…参数)=>{
const now={};
current.value=现在;
返回承诺。解析(args)
.然后((args)=>fn(…args))
。然后((解析)=>
current.value==现在
决定
:承诺。拒绝(替换)
);
};
};
const later=(值、时间)=>
新承诺((决议)=>
setTimeout(()=>解析(值),时间)
);
常量apiCall=(值)=>
//值长度为1时较慢
value.length==1
? later(值,1000)//需要一秒钟
:以后(值,100)//需要100毫秒
持续工作=最后(全部);
常量Api=({Api,title})=>{
const[value,setValue]=React.useState(“”);
const[apireult,setapireult]=React.useState(“”);
React.useffect(()=>{
api(值)。然后((解析)=>{
console.log(标题“已解决”,已解决);
SetapResult(解决);
});
},[api,标题,价值];
返回(
{title}
api结果:{apireult}
setValue(e.target.value)}
/>
);
};
常量应用=()=>(
);
ReactDOM.render(,document.getElementById('root'))

使用JavaScript的AbortController。Its专门用于取消网络请求


看看这个

你已经标记了它,那么你有没有在Axios中查找如何取消请求?如前所述,它被称为“去抖动”。基本上,您为每个更改设置了一个超时(比如500毫秒),在这个超时结束时,您将检查值是否没有更改,只有在这个时候请求才会通过API。在线阅读更多信息,我确信react内置了一些dobounce机制。@vladkatz不是,我会补充一个答案soon@HMR同意他所要求的不是去抖动,但他所要求的行为是去抖动可以带来更好的性能和更少的APIcalls@vladkatz见答案,debounce不会始终解决基于用户输入发出异步请求的问题:
异步结果解析的顺序可能不是用户输入的顺序
FWIW,SWR库已经执行了相同的重复数据消除;它在内部保存了最后一个请求的时间戳,并且只接受带有相同时间戳的响应:@HMR,您能在代码中提供一些信息吗?虽然这是我所需要的,但这对我来说是全新的,所以我不太明白它在做什么。@Yorbjörn
last
函数是一个结束函数,它返回一个承诺(apiCall)并将调用该函数,但仅在上次调用该函数时才解析该承诺:
我下面介绍的方法是在发出新请求时拒绝异步承诺
好的,我理解curried函数的概念,有一件事我还不太清楚,那就是我如何用这个实现我的GET请求。假设我需要从这个链接获取我的数据
https://${api_uri}/name/${value}
,我把url放在这个代码的什么地方,我可以在哪里看到它的响应。对不起,如果我问你,笨蛋questions@Yorbj假设您的get请求是由名为
apiCall
的函数完成的,那么
last(apiCall)
将返回一个函数,该函数只有在最后调用时才会解析,所以
lastApiCall=last(apiCall)
lastApiCall(url)。然后…