如何更好的取消一个promise?

本文介绍了两种取消Promise执行的方法:一是通过reject方法模拟取消;二是利用Promise.race方法实现取消。这两种方法可以帮助开发者更好地控制异步操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个正在执行中的promise怎样被取消?

其实就像一个执行中的ajax要被取消一样,ajax有abort()进行取消,而且fetch api 也有了相关的规范-【AbortController】。

fetch 怎样取消?

先来看下如何取消一个fetch请求

const url = "https://bigerfe.com/api/xxxx"
let controller;
let signal;

function requestA(){
 if (controller !== undefined) {
        controller.abort(); //终止请求
    }

    if ("AbortController" in window) {
        controller = new AbortController;
        signal = controller.signal;
    }

    fetch(url, {signal})
        .then((response) => {
            //do xxx
            updateAutocomplete()
        })
        .catch((error) => {
            //do xxx
            handleError(error);
        })
    });
}

怎样实现实现promise的取消?

方案1 - 借助reject 方法

我们都知道一个promise对象状态的改变是通过resolve和reject来执行的。那是不是可以借助reject方法来模拟呢?

上代码

//返回一个promise和abort方法
function getPromise() {
  let _res, _rej;
  
  const promise = new Promise((resolve, reject) => {
    _res = resolve;
    _rej = reject;
    setTimeout(() => {
      resolve('123')
    }, 5000);
  });
  return {
    promise,
    abort: () => {
      _rej({
        name: "abort",
        message: "the promise is aborted",
        aborted: true,
      });
    }
  };
}

const { promise, abort } = getPromise();
promise.then(console.log).catch(e => {
  console.log(e);
});

abort();

上面的方法可以正常执行,但是不够通用,可以将Promise构造函数内的逻辑提取出来,作为一个回调传进去。

改造一下

function getPromise(cb) {
  let _res, _rej;
  
  const promise = new Promise((res, rej) => {
    _res = res;
    _rej = rej;
    cb && cb(res,rej);
  });
  return {
    promise,
    abort: () => {
      _rej({
        name: "abort",
        message: "the promise is aborted",
        aborted: true,
      });
    }
  };
}

//主逻辑提取出来
function runCb(resolve,reject){
    setTimeout(()=>{
        resolve('1111')
    },3000)
}

const { promise, abort } = getPromise(runCb);
promise.then(console.log).catch(e => {
  console.log(e);
});

方案2  - 借助 Promise.race() 方法

相信大家都知道race方法的作用,这里还是简单介绍下。

当有若干个promise, p1, p2, p3…在调用, let p = Promise.race([p1, p2, p3,…])的时候,返回的p也是一个promise。那么p什么时候会被resolve或者被reject呢?

看race我们知道它是竞速或赛跑的意思,所以p1, p2, p3 … 最先一个被resolve或者被reject的结果就是p的resolve或者reject的结果。所以后续的promise的resolve和reject都不会再被执行了。

代码很简单,其实够短小精悍。

//传入一个正在执行的promise
function getPromiseWithAbort(p){
    let obj = {};
    //内部定一个新的promise,用来终止执行
    let p1 = new Promise(function(resolve, reject){
        obj.abort = reject;
    });
    obj.promise = Promise.race([p, p1]);
    return obj;
}

调用

var promise  = new Promise((resolve)=>{
 setTimeout(()=>{
  resolve('123')
 },3000)
})

var obj = getPromiseWithAbort(promise)

obj.promise.then(res=>{console.log(res)})

//如果要取消
obj.abort('取消执行')

借助race方法明显的更简洁,更易用。

最后

其实取消promise执行和取消请求是一样的,并不是真的终止了代码的执行,而是对结果不再处理。另外fetch api虽然增加了新的标准实现,但仍然存在兼容问题,而且只能在浏览器中使用。那么非浏览器的环境中呢?比如RN?所以如果想要达到一种通用的方式,那么本文的取消promise的方式应该是个不错的方式。

目前知名的axios库也有abort能力,回头看下它的实现方式,也欢迎小伙伴们留言讨论。

---end,希望对你有用。

点个『在看』支持下 

### OSPF Point-to-Multipoint Configuration with MGRE Tunneling Explanation and Setup Guide #### Understanding the Basics of OSPF Point-to-Multipoint Networks In a point-to-multipoint network type within OSPF, routers do not elect Designated Routers (DRs) or Backup Designated Routers (BDRs). Neighbors are established directly between endpoints. The default Hello interval is set to 30 seconds while the Dead interval stands at 120 seconds[^1]. This configuration simplifies neighbor establishment but requires careful planning when integrating advanced features like Multi-Point GRE tunnels. #### Introduction to Multi-Point GRE Tunnels Multi-Point GRE (mGRE) allows multiple remote sites to connect through a single virtual interface on an endpoint device without requiring individual physical interfaces for each connection. mGRE can significantly reduce complexity in hub-and-spoke topologies by enabling dynamic tunnel creation based on IPsec policies or other criteria. #### Combining OSPF Point-to-Multipoint Network Type with mGRE When combining these two technologies: - **Hub Router**: Configured as both ends of all spokes' mGRE sessions. - **Spoke Routers**: Each configured individually pointing back towards the central hub router's public address over which they will establish their respective mGRE session(s). The combination leverages OSPF’s ability to form adjacencies easily across non-broadcast multi-access networks such as those created via mGRE tunnels. It also benefits from OSPF's inherent support for point-to-multipoint configurations where DR/BDR elections aren't necessary due to direct adjacency formation among participating nodes. #### Example Configuration Steps for Hub Router Using Huawei CLI Syntax Below demonstrates how one might configure this scenario using commands similar to what would be found in a typical enterprise-grade environment provided by vendors like Huawei. ```shell # Enter system view mode system-view # Create loopback interface used for establishing mGRE connections interface LoopBack0 ip address 192.168.1.1 255.255.255.255 # Configure real Ethernet port that connects outside world interface GigabitEthernet0/0/1 ip address dhcp # Define mGRE template tunnel-template gre multipoint name mgre-tpl source-interface LoopBack0 destination any # Apply mGRE settings onto actual tunnel interface interface Tunnel0 undo ip address tunnel-protocol gre multipoint apply tunnel-template mgre-tpl ospf enable area 0 ``` For spoke routers, replace `source-interface` command under `tunnel-template` section accordingly depending upon local addressing scheme; ensure consistency throughout entire deployment regarding naming conventions applied here too. #### Verification Commands After Setup Completion Once completed successfully, verify operation status utilizing following instructions available inside most modern networking gear including models produced by companies mentioned earlier: ```shell display ospf peer brief # Check current state of OSPF peers display ip routing-table # Review learned routes after convergence has occurred ping -a <Source_IP> <Destination_IP> # Test reachability between different segments involved ``` --related questions-- 1. How does changing OSPF hello/dead timers affect stability in large-scale deployments? 2. What considerations should administrators take into account before implementing mGRE solutions? 3. Can you explain more about configuring OSPF route-id specifically for devices running OSPF protocol? 4. In what scenarios could deploying OSPF stub areas improve performance compared against standard ones?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zz_jesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值