取消JavaScript Promise

4

我正在尝试取消一个Promise,如下所示:

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();

但是我无法取消它。我在这里做错了什么?


如果cancel被拒绝,cancel.then()将不会被执行。 - axiac
@BenjaminGruenbaum在https://dev59.com/C10a5IYBdhLWcg3whJDW上提供了其他取消Promise的方法,尽管我不认为这是一个重复的问题。 - Ry-
4个回答

1
在你的代码中,你已经将一个完整的(被拒绝的)Promise传递给了函数。在尝试取消Promise之后cancel=Promise.resolve();不会对传递给example的Promise产生任何影响,因为你只是创建了一个新的已解决的Promise。
如果你想要取消正在运行的进程,那么你可能需要选择这样的解决方案:
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()

0

你已经将一个被拒绝的 Promise 赋值给了一个变量,将这个被拒绝的 Promise 传递到了你的函数中,并将一个已解决的 Promise 赋值给了该变量。该变量所取的两个值是不相关的,而且你无法改变已经 settled 的 Promise 的状态。

传入一个可以被解决的 Promise:

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();


0

由于取消被设置为拒绝,因此执行部分

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

永远不会被执行,因此您必须解决它,而不是拒绝它

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


我猜OP想在调用“example”之后取消执行,否则调用“example”就没有意义。 - t.niese
@t.niese。他发布了一段代码,只是为了澄清,我想。他的实现可能会有所不同。 - Sibiraj

0

因为您正在传递被拒绝的 Promise。如果您想让 cancel.then() 块运行,请传递已解决的 Promise。

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();


但是如果已经知道必须取消进程,那么为什么OP还要调用example呢? - t.niese

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接