如果一个并行函数已经失败,阻止该函数继续运行(使用jQuery $.when())
Preventing a function from running if a parallel function has already failed (using jQuery $.when())
我有一个相当复杂的异步函数系列,我在jQuery deferred的帮助下链接它们。
实际上我有两个并行的函数流,后面跟着应该在并行流完成后串行执行的函数。下面是一个示例(它们是现实生活中的AJAX调用):
function makeOmelette() {
$.when(
crackEggs().then(beatEggs),
washTomatos().then(chopTomatos)
).then(mixEggsAndTomatos).then(fryEggsAndTomatos).done(function() {
msg('Omelette is ready!');
}).fail(function() {
msg('Oh no, omelette fail!');
});
}
最后的done()
和fail()
处理程序处理成功或失败。我希望fail()
处理程序执行一旦出现任何问题,在链的任何地方,并为所有进一步的执行停止。
大多数情况下,这是有效的——除了一种情况。如果打蛋失败了,那么西红柿仍然要清洗和切碎——即使在这些任务中的任何一个开始时已经发生了失败。同样,如果洗番茄失败,也不会阻止crackegg和beatEggs函数的运行。
你可以在这里看到一个例子。
我对此的担忧是,在我的实际代码中,我不希望浏览器向服务器发出AJAX调用,如果由于整个过程已经失败而没有意义,那么这可能会潜在地改变状态。
有办法做我想做的吗?我想我可以为每个并行任务单独附加失败处理程序,但我想知道是否有一种不那么冗长/重复的方法。
谢谢!
为状态添加一个变量。例如在done( var status = 1 )
和fail( var status = 2
内部,然后在运行并行函数之前放一个简单的语句,以便它不会运行status = 2
。
Try (this pattern)
html<input type="button" value="reject" />
<input type="button" value="resolve" /> <output></output> <output></output>
<div id="messages"></div>
js
$(function () {
$("input").on("click", function (e) {
var dfd = new $.Deferred();
$("#messages").children().remove();
makeOmelette(this.value);
function makeOmelette(resolveReject, dfd) {
// dfd = dfd;
$.when(
// `crackEggs("resolve")`, `crackEggs("reject")`
crackEggs(resolveReject),
washTomatos())
.done(function (a, b) {
if (a === "rejected") {
err();
};
if (a === "resolved") {
beatEggs();
chopTomatos();
mixEggsAndTomatos();
fryEggsAndTomatos();
success();
};
});
};
function success() {
dfd.done(function (s) {
msg('Omelette is ready!');
$("output:first").val(s);
})
};
function err() {
dfd.fail(function (e) {
msg('Oh no, omelette fail!');
$("output:first").val(e);
});
};
dfd.always(function () {
$("output:last").val(dfd.state() + " at " + $.now())
});
function crackEggs(_resolveReject) {
(_resolveReject === "reject"
? dfd.reject(_resolveReject + " called at " + $.now())
: dfd.resolve(_resolveReject + " called at " + $.now())
);
msg('Cracking eggs');
return dfd.state();
}
function beatEggs() {
msg('Beating eggs');
return dfd.state();
}
function washTomatos() {
msg('Washing tomatos');
return dfd.state();
}
function chopTomatos() {
msg('Chopping tomatos');
return dfd.state();
}
function mixEggsAndTomatos() {
msg('Mixing eggs and tomatos');
return dfd.state();
}
function fryEggsAndTomatos() {
msg('Frying eggs and tomatos');
return dfd.state();
}
function msg(text) {
$('#messages').append('<p>' + text + '</p>');
}
});
});
JSFiddle https://jsfiddle.net/guest271314/WWF68/
相关文章:
- 关注函数运行过的表单字段(新手)
- 在函数运行时显示对话
- Javascript - 加载函数运行时未定义的变量
- Javascript变量在函数运行后不断重置自身
- 如何让 setTimeout 函数运行,然后停止使用循环
- 如何在函数运行之前隐藏 CSS
- 使用 .on 函数运行 jQuery 声明函数
- 在函数运行期间关闭 onClick
- jQuery停止函数运行两次
- Javascript:如何在函数运行完成之前对文档进行更改
- nodejs - 为什么我的异步函数运行两次
- 在传递值后停止函数运行
- 如何在 javascript 中的函数中将字符串作为函数运行
- 如何停止计时器函数运行
- 在浏览器空闲后保持设置超时函数运行
- JQuery:阻止一个函数运行,直到满足另一个函数条件“X”时间
- Angular 提供程序服务需要 init 函数运行一次
- 更新 Angular $interval 中的变量会导致其他函数运行
- 如何阻止此 setTimeout 函数运行
- 传入函数数组作为参数,对于函数中的每个函数运行函数