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

What is Makefile in Linux? How does it work?

Run and compile your programs more efficiently wi...

MySQL SQL statement analysis and query optimization detailed explanation

How to obtain SQL statements with performance iss...

Detailed explanation of HTML basics (Part 1)

1. Understand the WEB Web pages are mainly compos...

Web page experience: planning and design

1. Clarify the design direction <br />First,...

Recommended 20 best free English handwriting fonts

Jellyka BeesAntique Handwriting [ank]* Jellyka Cut...

Summary of pitfalls in importing ova files into vmware

Source of the problem As we all know, all network...

Detailed explanation of pipeline and valve in tomcat pipeline mode

Preface In a relatively complex large system, if ...

Web page layout should consider IE6 compatibility issues

The figure below shows the browser viewing rate i...

Vue implementation example using Google Recaptcha verification

In our recent project, we need to use Google robo...

Detailed discussion of InnoDB locks (record, gap, Next-Key lock)

Record lock locks a single index record. Record l...

Difference between MySQL update set and and

Table of contents Problem Description Cause Analy...

A complete list of commonly used MySQL functions (classified and summarized)

1. Mathematical Functions ABS(x) returns the abso...

Implementation example of react project from new creation to deployment

Start a new project This article mainly records t...

Solution to MySQL remote connection failure

I have encountered the problem that MySQL can con...

Problems and solutions encountered when connecting node to mysql database

I installed a new version of MySQL (8.0.21) today...