Javascript 只让最后一个API调用通过
因此,我有一个inputfield,当您在其中键入内容时,它会对我们的后端进行API调用,我遇到的问题是: 假设我们正在进行打字测试,我将对此进行4次调用:Javascript 只让最后一个API调用通过,javascript,reactjs,api,axios,Javascript,Reactjs,Api,Axios,因此,我有一个inputfield,当您在其中键入内容时,它会对我们的后端进行API调用,我遇到的问题是: 假设我们正在进行打字测试,我将对此进行4次调用: t te tes 试验 因为调用't'比'test'花费的时间要长得多,所以最后将加载来自't'的数据。这意味着我没有从“测试”中获取请求的数据 我的问题是,你有没有办法取消之前的请求?('t','te','tes')只让你最后一个电话接通?或者这只是优化API速度的性能 我已经尝试过超时半秒,但问题有时仍然存在。当您对用户输入进行异
- t
- te
- tes
- 试验
我已经尝试过超时半秒,但问题有时仍然存在。当您对用户输入进行异步调用时,异步结果解析的顺序可能不是用户输入的顺序(因此不是去盎司问题)。当用户键入
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örnlast
函数是一个结束函数,它返回一个承诺(apiCall)并将调用该函数,但仅在上次调用该函数时才解析该承诺:我下面介绍的方法是在发出新请求时拒绝异步承诺
好的,我理解curried函数的概念,有一件事我还不太清楚,那就是我如何用这个实现我的GET请求。假设我需要从这个链接获取我的数据https://${api_uri}/name/${value}
,我把url放在这个代码的什么地方,我可以在哪里看到它的响应。对不起,如果我问你,笨蛋questions@Yorbj假设您的get请求是由名为apiCall
的函数完成的,那么last(apiCall)
将返回一个函数,该函数只有在最后调用时才会解析,所以lastApiCall=last(apiCall)
和lastApiCall(url)。然后…