【发布时间】:2017-01-09 18:20:29
【问题描述】:
问题:需要取消承诺
是否可以在执行过程中取消或忽略一个promise并在运行时将其替换为另一个promise,以便仅解决其当前状态?
在生产中,我使用 angular $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 应该指向那个执行上下文。
【问题讨论】:
-
您能否提供更多关于您希望完成的任务的背景信息?这可能有助于我们了解解决此问题的最佳方法。
-
一个承诺被解决一次。也许我错了,但您可以使用两个 Promise 并使用
Promise.race来收听第一个已解决的 Promise。你还需要一些逻辑来拒绝第一个承诺。 -
"
.then()被调用了两次。" 不应该。.then只附加一个承诺。创建一个新的 Promise 并将其分配给mypromise并不会神奇地移动前一个 Promise 的所有回调。在你打电话给strangeFunc()之后,你有一个未处理的承诺。 -
不,
mypromise已被使用后,您无法将其换出,但您可以更改解决方式。 -
@Bergi 为什么不呢?它只是一个变量。
标签: javascript ecmascript-6 angular-promise es6-promise