在一个承诺被拒绝后,Promise.race继续运行

时间:2019-07-13 09:01:12

标签: javascript promise cancellation

promise.race是否不应该在其中一个被拒绝/解决后终止所有promise?

var cancelDeferred = new cancellation()

Promise.race([cancelDeferred.promise, new Promise( (res, req) => {
	setTimeout(() =>{
		console.log("hey")
	}, 2000)

})]).catch(e =>{
	console.log(e)
})

setTimeout(() => {cancelDeferred.cancel()}, 500);


function cancellation () {
    const token = {};
  
    token.promise = new Promise((_, reject) => {
      token.cancel = () => reject(new Error('cancelled'));
    });
  
    return token;
  }

在此代码中,一个承诺在500毫秒后被取消,因此应该导致.catch正确登录控制台日志?

不,它仍然显示“嘿”,这是为什么?

1 个答案:

答案 0 :(得分:1)

这是正常行为。并不是因为Promise拒绝,setTimeout才会被取消。 Promise.race为您提供了一个承诺,只要任何给定的承诺都被拒绝(或全部履行,则实现)。它不会中断任何仍在等待中的异步代码。在Promise.race返回的承诺解决之后,它将对传递给它的任何其他承诺的任何结算一无所知,但不会阻止异步代码执行。

setTimeout有其自己的“合同”,只有在致电clearTimeout时才能被打破。没有承诺拒绝不能阻止调用setTimeout回调。

要使其正常运行,您需要致电clearTimeout

var cancelDeferred = cancellation()
var clearDeferred = delay(2000);

Promise.race([cancelDeferred.promise, clearDeferred.promise]).catch(e =>{
    console.log("catch", e.message)
    clearDeferred.clear();
})

setTimeout(() => {cancelDeferred.cancel()}, 500);


function cancellation () {
    const token = {};
  
    token.promise = new Promise((_, reject) => {
        token.cancel = () => reject(new Error('cancelled'));
    });
    return token;
}

function delay(ms) {
    const token = {};

    token.promise = new Promise(() => {
        const timer = setTimeout(() => console.log("hey"), ms);
        token.clear = () => {
            clearTimeout(timer);
            console.log("timer cleared");
        }
    });
    return token;
}