中止上一个后无法发出新的获取请求

Posted

技术标签:

【中文标题】中止上一个后无法发出新的获取请求【英文标题】:Can't make new fetch request after aborting previous 【发布时间】:2020-08-14 12:42:34 【问题描述】:

我需要更改一个参数,该参数定义了我的请求应该来自哪些数据,而且这个应用程序需要定期刷新。如果用户在未完成的请求中更改参数,事情就会开始变得奇怪,并且会发生一些意外的行为。

所以我的方法是在开始新请求之前中止所有先前的请求,但是在使用await controller.abort() 之后似乎永远不会触发下一个请求,我是否需要清除信号或类似的东西?

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);

发生的情况是secondData 始终是undefined,实际上这第二个请求从未发生(查看网络流量)。如果我在.abort() 执行后停止源并尝试运行await fetchData(url2),它会提示一个错误,说Uncaught SyntaxError: await is only valid in async function 或者如果我尝试在没有await 的情况下运行它,它会返回一个未决的承诺,但实际的请求无处可去可以在流量标签中看到。


已解决

应用我在函数上创建的包装器上的建议,每次都调用新的控制器。

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);

【问题讨论】:

【参考方案1】:

您对两个不同的请求使用相同的AbortController。在AbortController 上调用.abort() 后,您已经更新了AbortSignal 的状态,这会导致第二个请求无效。

如果您想要这种行为,您应该为每个请求使用单独的AbortController。当然,如果您希望能够一次性中止所有请求,则将 AbortController 重复用于多个 fetch 请求是完全可以接受的。

其他几点...

.abort() 是一个同步方法,它返回void,因此在调用.abort() 时不需要await 前缀。 在您的代码示例中,第一个请求将永远不会中止,因为您正在等待fetch 请求,该请求将在调用.abort() 之前完成。

【讨论】:

以上是关于中止上一个后无法发出新的获取请求的主要内容,如果未能解决你的问题,请参考以下文章

如何中止获取请求并立即开始新的请求?

请求中止无法创建 SSL/TLS 安全通道 - HttpWebRequest

如何中止Ember Data发出的HTTP请求?

如何中止获取请求?

请求被中止:无法创建 SSL/TLS 安全通道。System.Net.WebException

在 AngularJS 中中止挂起的 ajax 请求