【问题标题】:How to abort a fetch request?如何中止获取请求?
【发布时间】:2017-06-19 04:55:59
【问题描述】:

我一直在使用新的fetch API 而不是旧的XMLHttpRequest

这很棒,但我缺少一个关键功能,xhr.abort()

我找不到任何有关获取该功能的信息。

谢谢。

更新: 用于中止提取的 hacky 解决方法https://github.com/Morantron/poor-mans-cancelable-fetch

基本上你在 web worker 中启动 fetch 并取消 web worker 以中止 fetch

【问题讨论】:

标签: javascript ecmascript-6


【解决方案1】:

它仍然是一个悬而未决的问题 所有相关的讨论都可以在这里找到

https://github.com/whatwg/fetch/issues/447 :(

【讨论】:

    【解决方案2】:

    可以通过 AbortController 中止获取:

    export function cancelableFetch(reqInfo, reqInit) {
      var abortController = new AbortController();
      var signal = abortController.signal;
      var cancel = abortController.abort.bind(abortController);
    
      var wrapResult = function (result) {
        if (result instanceof Promise) {
          var promise = result;
          promise.then = function (onfulfilled, onrejected) {
            var nativeThenResult = Object.getPrototypeOf(this).then.call(this, onfulfilled, onrejected);
            return wrapResult(nativeThenResult);
          }
          promise.cancel = cancel;
        }
        return result;
      }
    
      var req = window.fetch(reqInfo, Object.assign({signal: signal}, reqInit));
      return wrapResult(req);
    }
    

    用法示例:

    var req = cancelableFetch("/api/config")
      .then(res => res.json())
      .catch(err => {
        if (err.code === DOMException.ABORT_ERR) {
          console.log('Request canceled.')
        }
        else {
          // handle error
        }
      });
    
    setTimeout(() => req.cancel(), 2000);
    

    链接:

    1. https://developers.google.com/web/updates/2017/09/abortable-fetch
    2. https://developer.mozilla.org/en-US/docs/Web/API/AbortController

    【讨论】:

      【解决方案3】:

      我通常使用类似的东西,类似于@ixrock。

      // Fetch and return the promise with the abort controller as controller property
      function fetchWithController(input, init) {
        // create the controller
        let controller = new AbortController()
        // use the signal to hookup the controller to the fetch request
        let signal = controller.signal
        // extend arguments
        init = Object.assign({signal}, init)
        // call the fetch request
        let promise = fetch(input, init)
        // attach the controller
        promise.controller = controller
        return promise
      }
      

      然后用

      替换正常的 fetch
      let promise = fetchWithController('/')
      promise.controller.abort()
      

      【讨论】:

        猜你喜欢
        • 2019-09-03
        • 1970-01-01
        • 2020-02-21
        • 2021-12-15
        • 2011-05-09
        • 2011-05-31
        • 2016-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多