javascript – 取消vanilla ECMAScript 6 Promise链
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 取消vanilla ECMAScript 6 Promise链,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4835字,纯文字阅读大概需要7分钟。
内容图文
有没有一种方法可以清除JavaScript Promise实例的.thens?
我在QUnit之上编写了一个JavaScript测试框架.该框架通过在Promise中运行每个测试框架来同步运行测试. (抱歉这个代码块的长度.我尽可能地评论它,所以感觉不那么乏味.)
/* Promise extension -- used for easily making an async step with a
timeout without the Promise knowing anything about the function
it's waiting on */
$$.extend(Promise, {
asyncTimeout: function (timeToLive, errorMessage) {
var error = new Error(errorMessage || "Operation timed out.");
var res, // resolve()
rej, // reject()
t, // timeout instance
rst, // reset timeout function
p, // the promise instance
at; // the returned asyncTimeout instance
function createTimeout(reject, tempTtl) {
return setTimeout(function () {
// triggers a timeout event on the asyncTimeout object so that,
// if we want, we can do stuff outside of a .catch() block
// (may not be needed?)
$$(at).trigger("timeout");
reject(error);
}, tempTtl || timeToLive);
}
p = new Promise(function (resolve, reject) {
if (timeToLive != -1) {
t = createTimeout(reject);
// reset function -- allows a one-time timeout different
// from the one original specified
rst = function (tempTtl) {
clearTimeout(t);
t = createTimeout(reject, tempTtl);
}
} else {
// timeToLive = -1 -- allow this promise to run indefinitely
// used while debugging
t = 0;
rst = function () { return; };
}
res = function () {
clearTimeout(t);
resolve();
};
rej = reject;
});
return at = {
promise: p,
resolve: res,
reject: rej,
reset: rst,
timeout: t
};
}
});
/* framework module members... */
test: function (name, fn, options) {
var mod = this; // local reference to framework module since promises
// run code under the window object
var defaultOptions = {
// default max running time is 5 seconds
timeout: 5000
}
options = $$.extend({}, defaultOptions, options);
// remove timeout when debugging is enabled
options.timeout = mod.debugging ? -1 : options.timeout;
// call to QUnit.test()
test(name, function (assert) {
// tell QUnit this is an async test so it doesn't run other tests
// until done() is called
var done = assert.async();
return new Promise(function (resolve, reject) {
console.log("Beginning: " + name);
var at = Promise.asyncTimeout(options.timeout, "Test timed out.");
$$(at).one("timeout", function () {
// assert.fail() is just an extension I made that literally calls
// assert.ok(false, msg);
assert.fail("Test timed out");
});
// run test function
var result = fn.call(mod, assert, at.reset);
// if the test returns a Promise, resolve it before resolving the test promise
if (result && result.constructor === Promise) {
// catch unhandled errors thrown by the test so future tests will run
result.catch(function (error) {
var msg = "Unhandled error occurred."
if (error) {
msg = error.message + "\n" + error.stack;
}
assert.fail(msg);
}).then(function () {
// resolve the timeout Promise
at.resolve();
resolve();
});
} else {
// if test does not return a Promise, simply clear the timeout
// and resolve our test Promise
at.resolve();
resolve();
}
}).then(function () {
// tell QUnit that the test is over so that it can clean up and start the next test
done();
console.log("Ending: " + name);
});
});
}
如果测试超时,我的超时Promise将在测试中断言.fail()以便测试被标记为失败,这一切都很好,但测试继续运行,因为测试Promise(结果)仍在等待解决它.
我需要一个好方法取消我的测试.我可以通过在框架模块this.cancelTest上创建一个字段来完成它,并在测试中经常检查(例如在每次then()迭代的开始)是否取消.但是,理想情况下,我可以使用$$(at).on(“timeout”,/ * here here * /)来清除结果变量中剩余的then()s,以便其余的测试都不会运行.
这样的事情存在吗?
快速更新
我尝试使用Promise.race([result,at.promise]).它没用.
更新2混乱
为了解锁我,我在测试想法中添加了几行mod.cancelTest / polling. (我也删除了事件触发器.)
return new Promise(function (resolve, reject) {
console.log("Beginning: " + name);
var at = Promise.asyncTimeout(options.timeout, "Test timed out.");
at.promise.catch(function () {
// end the test if it times out
mod.cancelTest = true;
assert.fail("Test timed out");
resolve();
});
// ...
}).then(function () {
// tell QUnit that the test is over so that it can clean up and start the next test
done();
console.log("Ending: " + name);
});
我在catch语句中设置了一个断点,它正被击中.我现在困惑的是没有调用then()语句.想法?
更新3
想出最后一件事. fn.call()抛出了一个我没有抓到的错误,所以测试承诺在at.promise.catch()解决之前就拒绝了.
解决方法:
Is there a method for clearing the
.then
s of a JavaScript Promise instance?
不.至少在ECMAScript 6中没有.默认情况下,Promises(以及他们当时的处理程序)是不可取消的(不幸的是).关于如何以正确的方式做到这一点的es-discuss(例如here)有一些讨论,但无论采取何种方法,它都不会落在ES6中.
目前的观点是子类化将允许使用您自己的实现创建可取消的承诺(不确定它将如何工作).
直到语言委员会找到最好的方法(ES7希望?),你仍然可以使用userland Promise实现,其中许多功能取消.
目前的讨论见于https://github.com/domenic/cancelable-promise和https://github.com/bergus/promise-cancellation草案.
内容总结
以上是互联网集市为您收集整理的javascript – 取消vanilla ECMAScript 6 Promise链全部内容,希望文章能够帮你解决javascript – 取消vanilla ECMAScript 6 Promise链所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。