JS Promise未定义的行为



问题:需要取消承诺

是否可以在执行过程中取消忽略承诺,并在运行时用另一个承诺替换它,以便只解析其当前状态?

在生产中,我使用角度$timeout,它定义了cancel()方法。我模仿它在节点中运行:

//Mimic AngularJS's $timeout
function MyTimeout(delay) {
var t = null;
var p = new Promise(function (resolve) {
t = setTimeout(resolve, delay);
});
p.realtimeout = t;
return p;
}
MyTimeout.cancel = function (myto) {
clearTimeout(myto.realtimeout);
/*
* there is no way to appropriately cancel an existing Promise
* the best I can do in try and change the state of myto to a rejected
* Promise. Which doesn't help here since it doesn't truly cancel the last
* Promise...
*/
myto = Promise.reject("some reason");
};

var x = null;
function changeState() {
var delay;
if (x === null) {
delay = 1000;
} else {
MyTimeout.cancel(x);
delay = 3000;
}
x = MyTimeout(delay).then(print_delay);
function print_delay() {
console.log("EXECUTED: %s", delay);
}
}

changeState();
x.then(function () {
console.log("DONE");
}).catch(console.error);
changeState();

NodeJS输出

(node:12461) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): some reason
(node:12461) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
EXECUTED: 1000
DONE
EXECUTED: 3000

预期结果EXECUTED: 3000应打印一次。由于标志被设置并且x已经被相应地设置。x应该指向该执行上下文。

mypromisex已经被使用后,您不能交换它,因为更改变量引用根本不会影响第一个promise及其处理程序。您需要影响您已经拥有的承诺的解析过程,为此,您需要以一种方式创建它,以便在之后更改resolve的调用时间/方式:

function variableDelay(x) {
var timer = 0;
var end;
return {
promise: new Promise(resolve => {
end = () => {
timer = -1;
resolve(x);
};
}),
setDelay(d) {
if (timer < 0) throw new Error("too late");
if (timer > 0) clearTimeout(timer);
timer = setTimeout(end, d);
return this;
}
};
}

const {promise:x, setDelay:changeState} = variableDelay();
changeState(1000);
x.then(() => {
console.log("DONE");
}).catch(console.error);
changeState(3000);

最新更新