Fetch和Promise网络请求的取消

Published on
17

使用AbortController

const controller = new AbortController();
const signal = controller.signal;
fetch("https://www.baidu.com", { signal })
  .then((response) => response)
  .then((data) => console.log(data))
  .catch((err) => {
    if (err.name === "AbortError") {
      console.log("Fetch aborted");
    } else {
      console.error("Fetch error:", err);
    }
  });
//取消请求
controller.abort();

自定义Promise包装器

//二次封装Promise
class CancellablePromise {
  constructor(executor) {
    this._hasCanceled = false;
    this._promise = new Promise((resolve, reject) => {
      executor(
        (value) => (this._hasCanceled ? reject({ canceled: true }) : resolve(value)),
        (reason) => (this._hasCanceled ? reject({ canceled: true }) : reject(reason)),
      );
    });
  }
  cancel() {
    this._hasCanceled = true;
  }
  then(onFulfilled, onRejected) {
    return this._promise.then(onFulfilled, onRejected);
  }
  catch(onRejected) {
    return this._promise.catch(onRejected);
  }
} 

// 使用自定义的CancellablePromise
const cancellablePromise = new CancellablePromise((resolve, reject) => {
  setTimeout(() => resolve("Completed!"), 1000);
});

cancellablePromise.then(
  (result) => console.log(result),
  (err) => {
    if (err.canceled) {
      console.log("Promise was canceled");
    } else {
      console.error("Promise error:", err);
    }
  },
);
 
// 取消Promise
cancellablePromise.cancel();

虽然标准的Promise没有内置取消功能,但可以通过这些方法来实现取消逻辑,根据实际需求选择合适的方案。


Prev Post 让浏览器发出像QQ一样的右下角桌面消息提示
Next Post [wechat-need-web] 让微信网页版可用