【发布时间】:2013-01-16 09:33:49
【问题描述】:
我正在尝试将序列化逻辑强制用于网页上的一组异步活动。我相当确定我想使用 jQuery 延迟对象,但我遇到了一个问题,即我想要执行的函数取决于用户何时决定通过单击各种按钮进行选择。我正在使用以下 jsFiddle 想法寻求帮助:
考虑 4 个按钮的序列。单击时,每个按钮都会禁用自身并启用下一个按钮。每个按钮在启用之前不应设置其事件。只有在启用第三个按钮后,才能完成添加的任务(在本例中为警报)。
基本 HTML 代码
<button id="btn1">Click 1st</button>
<button id="btn2" disabled="disabled">Click 2nd</button>
<button id="btn3" disabled="disabled">Click 3rd</button>
<button id="btn4" disabled="disabled">Click 4th</button>
每一步的任务
var fnDoStageOne = function() {
$("#btn1").one("click", function(event, ui) {
$("#btn1").prop("disabled", true);
$("#btn2").prop("disabled", false);
//STAGE ONE IS ONLY DONE AFTER THIS POINT
});
};
var fnDoStageTwo = function() {
$("#btn2").one("click", function(event, ui) {
$("#btn2").prop("disabled", true);
$("#btn3").prop("disabled", false);
//STAGE TWO IS ONLY DONE AFTER THIS POINT
});
};
var fnDoStageThree = function() {
$("#btn3").one("click", function(event, ui) {
$("#btn3").prop("disabled", true);
$("#btn4").prop("disabled", false);
//STAGE THREE IS ONLY DONE AFTER THIS POINT
});
alert("Shouldn't see this if button 3 isn't active yet");
};
var fnDoStageFour = function() {
$("#btn4").one("click", function(event, ui) {
$("#btn4").prop("disabled", true);
alert("Task complete");
//STAGE FOUR IS ONLY DONE AFTER THIS POINT
});
};
不正确的控制逻辑
var oDeferredObj = $.Deferred();
oDeferredObj.then(fnDoStageOne);
oDeferredObj.then(fnDoStageTwo);
oDeferredObj.then(fnDoStageThree);
oDeferredObj.then(fnDoStageFour);
oDeferredObj.resolve();
jsfiddle 可以在这里看到:http://jsfiddle.net/sva79/
我最初的理解是,我可以使用 .then() 函数将函数链接到 deferred 中。显然,这不起作用,因为第 3 步中的附加任务会在页面加载时触发。我需要如何调整此场景的控制或逻辑以解决每个步骤,直到注册了相应的按钮按下?
【问题讨论】:
-
如果一个按钮被禁用,click事件永远不会触发,那么为什么不把所有的事件监听器绑定一次呢?
-
因为这特别代表了如何处理延迟对象的问题。我试图拼凑如何将它们用于更复杂的问题,所以我试图与一个我能真正理解的更简单的问题进行对比。
-
您在这里没有使用任何特定的延迟功能。你只是触发了四个连续的功能。您在此处尝试完成的操作与延迟无关。看我的回答。
-
延迟对象文档建议它应该用于跨异步事件流水线操作。我正在设置这些函数来表示需要流水线的操作。在前一个动作实际完成(单击按钮)之前,不应执行每个动作。我不清楚如何在当前采取的行动实际完成时发出信号。如果我应该使用延迟对象以外的功能,那很好,但解决方案代表了我遇到的一般问题,而不是需要在我的网页上修复的特定问题。
标签: javascript jquery jquery-deferred promise