I need to change a parameters that defines what data should come from my requests, also this application needs to refresh on a regular time interval. If the user changes the parameter in the middle of an unfinished request things start to behave strange and some unexpected behavior occurs.
So my approach was to abort all previous requests before starting the new ones, but after using await controller.abort()
it seems that the next requests are never triggered, Do I need to clear the signal or something like that?
const controller = new AbortController(); const async fetchData = (url, body = null) => { let data; const signal = controller.signal; const headers = { ... }; response = await fetch(url, body ? { method: "POST", body: JSON.stringify(body), signal, headers } : { headers, signal });; data = await response.json() return data } const firstData = await fetchData(url1, body1); await controller.abort(); const secondData= await fetchData(url2, body2);
What happens is that secondData
always is undefined
, actually this second request never happens (looking on network traffic). If I stop source and try to run await fetchData(url2)
after .abort()
has executed it prompts an erros saying that Uncaught SyntaxError: await is only valid in async function
or if I try to run it without await
it returns a pending promise, but the actual request is nowhere to be seen in traffic tab.
Solved
Applying what was suggested on the ansewr I created wrapper on the function, to call new controllers everytime.
let controller = null; let fetchData = null; const initializeFetchData = () => { const controller = new AbortController(); const async fetchData = (url, body = null) => { let data; const signal = controller.signal; const headers = { ... }; response = await fetch(url, body ? { method: "POST", body: JSON.stringify(body), signal, headers } : { headers, signal });; data = await response.json() return data } } initializeFetchData(); const firstData = await fetchData(url1, body1); controller.abort(); initializeFetchData(); const secondData= await fetchData(url2, body2);
Advertisement
Answer
You are using the sameAbortController
for two different requests. After calling .abort()
on theAbortController
you have updated the state of it’s AbortSignal
which then renders the second request void.
You should use a separate AbortController
for each request if you want this behavior. Of course, it is perfectly acceptable to reuse an AbortController
for multiple fetch
requests if you want to be able to abort all of them in one go.
A couple of other points…
.abort()
is a synchronous method which returnsvoid
so you do not need theawait
prefix when calling.abort()
.- In your code example, the first request will never be aborted as you are awaiting the
fetch
request, which will complete before the.abort()
is called.