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

Posted

技术标签:

【中文标题】如何中止获取请求并立即开始新的请求?【英文标题】:How do I abort fetch request and start a new one immediately? 【发布时间】:2019-09-03 06:37:53 【问题描述】:

以下是来自 MDN 的示例。有两个按钮。一个正在发送请求,另一个正在取消。

var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() 
  controller.abort();
  console.log('Download aborted');
);

function fetchVideo() 
  ...
  fetch(url, signal).then(function(response) 
    ...
  ).catch(function(e) 
    reports.textContent = 'Download error: ' + e.message;
  )

现在我的情况不同了。我有一个 query 参数,如果正在获取但未完成,并且 query 参数发生更改 - 我如何发送一个新请求自动取消之前的请求?

【问题讨论】:

你意识到这一点isn't supported on IE right?你的问题到底是什么?有没有办法做到这一点,是的。 Edge 上实际上支持 @Liam + IE 有 polyfills npmjs.com/package/abortcontroller-polyfill 误读了,锯边,没有在手机上阅读 如果AbortController 不可用,那么,明智地使用Promise.race(),您应该能够为自己设计一个可中止的Promise。它与将signal 传递给fetch() 的行为不同,但应用程序代码中的净效应是相同的。 @Roamer AbortController 的目标是向 fetch API 提供可取消的请求,这种设计原本就相当复杂;能够停止长时间运行的请求(例如在 MDN 的情况下,视频)。赛车承诺不会帮助中止任何事情。即使他们要求停止下载,您的用户仍将下载整个文件。但是,至少从 XHR2 开始,取消请求是可行的。因此,如果您需要对其进行 polyfill,您只需要返回使用 XHR 并 Promisify 它(需要注意的是,应在请求开始时声明消费者)。 【参考方案1】:

不确定我是否清楚,但据我了解,您的情况并没有什么不同。

基本相同,将控制器存储在您的逻辑可访问的位置,可能会取消它,如果需要,在发送新请求之前取消它:

let aborter = null; // make the aborter accessible
function getData(param) 
  // cancel pending request if any
  if(aborter) aborter.abort();
  // make our request cancellable
  aborter = new AbortController();
  const signal = aborter.signal;
  const url = 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png?rand=' + param;
  return fetch(url, signal)
  // clean up, not really needed but may help to know if there is a pending request
  .then(r => aborter = null; return r;)

// first request will get aborted
getData("foo")
  .then(r => console.log('foo done'))
  .catch(e => console.error('foo failed', e.name, e.message));
// will abort the previous one
getData("bar")
  .then(r =>  console.log('bar done'))
  .catch(e => console.error('bar failed', e.name, e.message))

【讨论】:

谢谢!!我做了一个react example 参考你的

以上是关于如何中止获取请求并立即开始新的请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何中止获取请求?

从 HTTP 到 HTTPS 的跨域请求立即中止

中止路由并继续.NET中的原始请求[重复]

AbortController 中止一个或多个 Web请求

AbortController 中止一个或多个 Web请求

jQuery UI 自动完成:中止请求