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

How to set MySQL foreign keys for beginners

Table of contents The role of foreign keys mysql ...

Solution to Vue3.0 error Cannot find module'worker_threads'

I'll record my first attempt at vue3.0. When ...

Database SQL statement optimization

Why optimize: With the launch of the actual proje...

How to avoid duplication of data when inserting in MySql batch

Table of contents Preface 1. insert ignore into 2...

MYSQL 5.6 Deployment and monitoring of slave replication

MYSQL 5.6 Deployment and monitoring of slave repl...

Mysql modify stored procedure related permissions issue

When using MySQL database, you often encounter su...

In-depth understanding of asynchronous waiting in Javascript

In this article, we’ll explore how async/await is...

How to correctly create MySQL indexes

Indexing is similar to building bibliographic ind...

A brief discussion on the maximum number of open files for MySQL system users

What you learn from books is always shallow, and ...

Detailed explanation of Strict mode in JavaScript

Table of contents Introduction Using Strict mode ...

How to use JavaScript to get the most repeated characters in a string

Table of contents topic analyze Objects of use So...

How to implement HTML Table blank cell completion

When I first taught myself web development, there...

Detailed tutorial on installing mysql on centos 6.9

1. Confirm whether MySQL has been installed. You ...