4

I am trying to cancel a promise as given below:

function example(cancel = Promise.reject()) {
    return new Promise((resolve, reject) => {
        const timer = setTimeout(() => resolve('jack-jack'), 5000);
        cancel.then((res) => {
            clearTimeout(timer);
            reject('cancelled'); 
        }, ()=>{})
    });
}
var cancel=Promise.reject(); 
example(cancel).then((res) => console.log('res handled:' + res)).catch((err) => console.log('err handled:' + err));
console.log('attempting cancellation of promise');
cancel=Promise.resolve();

However I am not able to cancel it. What am I doing wrong over here?

user7637745
  • 965
  • 2
  • 14
  • 27
user
  • 568
  • 5
  • 19
  • If `cancel` is rejected, `cancel.then()` is not executed. – axiac Jul 02 '18 at 14:01
  • @BenjaminGruenbaum has an answer with other ways to cancel things at https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise, though I don’t think it’s a duplicate. – Ry- Jul 02 '18 at 14:07

4 Answers4

1

In your code you pass already a complete (rejected) Promise to the function. And cancel=Promise.resolve(); after attempting cancellation of promise won't have any effect to promise that was passed to example because you just create a new resolved Promise.

If you want to cancel a running process then you might want choose such a solution:

function example(helper) {
  return new Promise((resolve, reject) => {
    helper.cancel = function() {
      clearTimeout(timer)
      reject('cancelled');
    }
    const timer = setTimeout(() => resolve('jack-jack'), 5000);

  });
}
var helper = {};
example(helper).then((res) => console.log('res handled:' + res)).catch((err) => console.log('err handled:' + err));

console.log('attempting cancellation of promise');
helper.cancel()
t.niese
  • 39,256
  • 9
  • 74
  • 101
0

You’ve assigned a rejected promise to a variable, passed the rejected promise into your function, and assigned a resolved promise to the variable. The two values the variable takes on are unrelated, and you can’t change the state of a settled promise.

Pass in a promise you can resolve:

let cancel;
let cancelPromise = new Promise((resolve) => {
    cancel = resolve;
});

example(cancelPromise).then(…).catch(…);
console.log('attempting cancellation of promise');
cancel();

function example(cancel = Promise.reject()) {
    return new Promise((resolve, reject) => {
        const timer = setTimeout(() => resolve('jack-jack'), 5000);
        cancel.then((res) => {
            clearTimeout(timer);
            reject('cancelled'); 
        }, ()=>{})
    });
}

let cancel;
let cancelPromise = new Promise((resolve) => {
    cancel = resolve;
});

example(cancelPromise)
    .then((res) => console.log('res handled:' + res))
    .catch((err) => console.log('err handled:' + err));
console.log('attempting cancellation of promise');
cancel();
Ry-
  • 218,210
  • 55
  • 464
  • 476
0

Because you are passing rejected promise. Pass the resolved promise if you want cancel.then() block to run.

function example(cancel = Promise.resolve()) {
  return new Promise((resolve, reject) => {
    console.log(cancel);
    const timer = setTimeout(() => {
      resolve('jack-jack'), 5000
    });
    cancel.then((res) => {
      console.log('CANCELLED');
      clearTimeout(timer);
      reject('cancelled');
    }, () => {})
  });
}
var cancel = Promise.resolve();
example(cancel).then((res) => console.log('res handled:' + res)).catch((err) => console.log('err handled:' + err));
console.log('attempting cancellation of promise');
cancel = Promise.resolve();
Munim Munna
  • 17,178
  • 6
  • 29
  • 58
dasfdsa
  • 7,102
  • 8
  • 51
  • 93
  • But then why should the OP call `example` at all if it is already known that the process has to be canceled? – t.niese Jul 02 '18 at 14:26
0

Since the cancel is set to reject, the then part

cancel.then((res) => { //you cannot use then for reject, as reject cannot be resolved.
    clearTimeout(timer);
     reject('cancelled'); 
}, ()=>{})

will never gets executed hence you have to resolve it, not reject it

function example(cancel = Promise.reject()) {
    return new Promise((resolve, reject) => {
        const timer = setTimeout(() => resolve('jack-jack'), 5000);
        cancel.then((res) => { //you cannot use then for reject
            clearTimeout(timer);
            reject('cancelled'); 
        }, ()=>{})
    });
}

var cancel = Promise.resolve(); // just change to resolve

example(cancel).then((res) => console.log('res handled:' + res)).catch((err) => console.log('err handled:' + err));

console.log('attempting cancellation of promise');
cancel=Promise.resolve(); // this will have no effect as you have already passed a reject
Sibiraj
  • 4,486
  • 7
  • 33
  • 57
  • I would guess the OP wants to cancel the execution after `example` was called, because otherwise it would not make sense to call `example`. – t.niese Jul 02 '18 at 14:25
  • @t.niese. he posted a piece of code just for clarification, I guess. His implementation could differ – Sibiraj Jul 03 '18 at 06:10