我有两个回调需要放在同一个项目的同一个
change
事件上。由于不值得讨论的原因,我需要将这些回调放在单独的 on
中,我无法将它们统一在单个 on
调用下。 所以我需要这些 on
调用来保持独立,例如:
$('body').on('change', '#my-div', function1);
$('body').on('change', '#my-div', function2);
现在,我内部有一个 AJAX 调用
function1
。我希望 function2
始终在 function1
执行完成后执行,包括在 function1
内收到 AJAX 响应之后。我询问了 ChatGPT,它建议我使用 $.Deferred()
:
let function1Deferred = $.Deferred();
function function1() {
function1Deferred = $.Deferred();
$.ajax({
url: 'your-url', // Replace with your URL
method: 'GET',
success: function(data) {
console.log("Function1 AJAX request completed");
function1Deferred.resolve();
},
error: function() {
function1Deferred.reject();
}
});
}
function function2() {
function1Deferred.done(function() {
console.log("Function2 is now executing after function1 has completed.");
});
}
不过,在我看来,这只能在第一次触发
change
事件时解决问题,因为不能保证 function1
会在 function2
之前先运行 - 因此不能保证在第二次触发以及 change
事件的第三个触发器等,function1Deferred = $.Deferred();
内的 function1
行将在 function2
运行之前运行,因此 function2
很可能是第一个运行的,并在后续运行时运行到最后change
事件的触发器。
我是否遗漏了一些东西,代码是否真正实现了我想要的效果,而我只是遗漏了一些关于
Deferred
在幕后如何工作的信息?如果是的话,我错过了什么?如果没有,我该如何解决我的问题并确保 function2
始终在事件的后续触发器上运行在 function1
之后,而不仅仅是在第一个事件上?
我只是想再次强调,我需要
on
函数的调用保持独立,我不能使用单个 on('change', '#my-div', newFunction)
调用,这不是在更大的上下文中解决我的问题的解决方案。
如所呈现的,代码不一定会执行您想要的操作。如果
function2
首先触发:
这里是 a demo,它将延迟对象显式设置为
null
以使其更加明显。如果单击“运行 F2+F1”按钮,您将收到“function1Deferred is null”错误。
考虑到限制,最简单的选择可能是将
function2
主体包装在 setTimeout
调用中:
setTimeout(() => function1Deferred.done(() => {
output.append("Running function 2\n");
}), 0);
这会将控制权返回给调用函数,从而允许其他处理程序在延迟对象上注册
done
回调之前执行。
现在,无论您单击哪个按钮,直到出现“功能 1 完成”消息之后,您才会看到“正在运行功能 2”消息。