4

I have series of promise chains, which took sufficient time to get completed. Below is the sample chain setup:

myJob1()
.then(myJob2)
.then(myJob3)
.then(myJob4)
.then(myJob5)
.then(myJob6)
.catch(myJobError);

In mean time when this job is running, if the person on UI think to cancel it, How can it be cancelled in whatever stage/function execution it is?

What can be the possible solution?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Manish Kumar
  • 1,131
  • 15
  • 28
  • Really need more info, eg. especially when you say client. Does your client have some form of RPC in place?. Cancelling a promise chain would be easy, but it's getting the command to the back end that's the tricky part. – Keith Aug 21 '17 at 12:03
  • 1
    Possible duplicate of [How to cancel an EMCAScript6 (vanilla JavaScript) promise chain](https://stackoverflow.com/questions/29478751/how-to-cancel-an-emcascript6-vanilla-javascript-promise-chain) – TheCog19 Aug 21 '17 at 12:04
  • You can't cancel, but you can do a reject. Which would then stop the rest of the then's from being called. You would have to test for something in each job, and if that test passed you would return a new rejected promise, ie `return Promise.reject('reason')` – Patrick Evans Aug 21 '17 at 12:05

2 Answers2

4

One alternative to modifying code for multiple job functions might be to check a user cancelled flag between jobs. If the granularity of this kind of checking is not too course, then you could asynchronously set a (somewhat) global cancelled flag and proceed along the lines of:

let userCancelled = false;
let checkCancel = function( data) {
    if( userCancelled)
        throw new Error( "cancelled by user"); // invoke catch handling
    return data; // pass through the data
}

myJob1()
 .then(myJob2).then( checkCancel)
 .then(myJob3).then( checkCancel)
 .then(myJob4).then( checkCancel)
 .then(myJob5).then( checkCancel)
 .then(myJob6).then( checkCancel)
 .catch(myJobError);

Don't forget that if you do check the cancelled flag inside a job, all you need to do is throw an error to have it bubble down the promise chain.

traktor
  • 17,588
  • 4
  • 32
  • 53
1

There is no way to cancel the promise (remember each of thens is returning a new promise) or clear the then callback.

Probably you are looking for something like redux-observable, where you can specify clause, until promise execution is actual.

See more in details: https://github.com/redux-observable/redux-observable/blob/master/docs/recipes/Cancellation.md

As alternative I may only suggest you to create and manage some flag which determines whether further process is needed or not:

// Inside each of promises in chain
if (notCancelled) {
    callAjax(params).then(resolve);
}

Or reject:

// Inside each of promises in chain
if (cancelled) {
    // Will stop execution of promise chain
    return reject(new Error('Cancelled by user'));
}
Artem
  • 1,937
  • 1
  • 14
  • 19