How to add abort function to promise in JS

How to add abort function to promise in JS

Overview

Promise has only three states: pending, resolve, and reject. Once an asynchronous promise is issued, after waiting (pending), it can only be successful or failed in the end, and it cannot be canceled (abort) in the middle.

There are two ways to provide abort functionality for promises:

  • Manually implement abort. After the cancellation is triggered, the asynchronously returned data is directly discarded (manual implementation is relatively safe)
  • Use the native method AbortController to interrupt the request (experimental method, compatible, not supported by IE)

There are two modes for manually implementing the abort method: both rely on the promise interface to implement it indirectly

Promise Race Method

let PromiseWithAbort = function(promise){
    let _abort = null;
    let Pabort = new Promise((res,rej)=>{
      _abort = function(reason ='abort !'){
        console.warn(reason);
        rej(reason);
      }
    });

    let race = Promise.race([promise,Pabort]);
    race.abort = _abort;
    console.log(promise,Pabort);
    return race;
  }

let p1 = new Promise(res=>{
   setTimeout(()=>{
      res('p1 success');
   },2000)
})

let testP = PromiseWithAbort(p1);

testP.then(res=>{
  console.log('success:',res);
},error=>{
  console.log('error:',error);
})

testP.abort();

// Result: reject: abort!

Repackaging promises

class PromiseWithAbort {
    constructor(fn){
      let _abort = null;
      let _p = new Promise((res,rej)=>{
        fn.call(null,res,rej);
        _abort = function(error='abort'){ rej(error); }
      })

      _p.abort = _abort;
      return _p;
    }
  } 


let testP = new PromiseWithAbort((res,rej)=>{
    setTimeout(() => {
      res(1);
    },1000);
  });

 testP.then(r=>{
    console.log('res:',r);
  },r=>{
    console.log('rej:',r);
  });

  testP.abort();
//Result: rej: abort

AbortController

(This is an experimental feature, belonging to the DOM specification, and some browsers are still under development.) The AbortController interface represents a controller object that allows you to abort one or more DOM requests when needed.

// Interrupt fetch request let controller = new AbortController();
  let signal = controller.signal;

 fetch('https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally',{signal}).then(r=>{
    console.log(r);
  });

  controller.abort();
// Result: Uncaught (in promise) DOMException: The user aborted a request.
//Interrupt a promise
class PromiseWithAbortController {
  constructor(fn,{signal}){
    if (signal && signal.aborted) {
      return Promise.reject(new DOMException('Aborted','AbortError'));
    }

    let _p = new Promise((resolve,reject)=>{
      fn.call(null,resolve,reject);
      if(signal){
        signal.addEventListener('abort',()=>{
          reject(new DOMException('Aborted','AbortError'));
        })
      }
    });

    return _p;
  }
}
let controller = new AbortController();
  let signal = controller.signal;
let testP2 = new PromiseWithAbortController((r,j)=>{
  setTimeout(() => {
    r('success');
  }, 1000);
},{signal});

testP2.then(r=>{
    console.log('res:',r);
  },r=>{
    console.log('rej:',r);
  });

  controller.abort();
  // Result: rej: DOMException: Aborted

Axios plugin comes with cancel function

//1. Use source token
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

//2. Through the outgoing function
const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

//Main: Requests using the same token can be canceled together

Axios is the most frequently used in current projects, so don't worry about canceling the request. The DOM-specified AbortController is not recommended due to compatibility reasons. If you need to implement it yourself, the first two methods in the article are safer (promise race method and repackage promise method).

The above is the details of how JS adds abort function to promise. For more information about JS, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • A Deep Dive into JavaScript Promises
  • Detailed explanation of Promises in JavaScript
  • Front-end JavaScript Promise
  • JS 9 Promise Interview Questions
  • Thoroughly understand JavaScript's Promise

<<:  Tomcat class loader implementation method and example code

>>:  Detailed graphic explanation of how to install and completely delete MySQL by decompression

Recommend

Detailed analysis of mysql MDL metadata lock

Preface: When you execute a SQL statement in MySQ...

Semantics: Is Html/Xhtml really standards-compliant?

<br />Original text: http://jorux.com/archiv...

Summary of 4 solutions for returning values ​​on WeChat Mini Program pages

Table of contents Usage scenarios Solution 1. Use...

Some small methods commonly used in html pages

Add in the <Head> tag <meta http-equiv=&q...

How to use nginx to configure access to wgcloud

The nginx configuration is as follows: Such as ht...

Solve the MySQL login 1045 problem under centos

Since the entire application needs to be deployed...

How to manually upgrade the node version under CentOs

1. Find the corresponding nodejs package, refer t...

How to configure VMware multi-node environment

This tutorial uses CentOS 7 64-bit. Allocate 2GB ...

Is a design that complies with design specifications a good design?

In the past few years of my career, I have writte...

Detailed explanation of MySQL precompilation function

This article shares the MySQL precompilation func...

A brief introduction to MySQL storage engine

1. MySql Architecture Before introducing the stor...

Nginx tp3.2.3 404 problem solution

Recently I changed Apache to nginx. When I moved ...

How to implement Echats chart large screen adaptation

Table of contents describe accomplish The project...

Solution to the automatic termination of docker run container

Today I encountered a problem when I used Dockerf...