我进入了一个新的凌乱代码库,没有任何可用的测试,并且我为此问题苦苦挣扎了很长时间。我不能使用任何ES6代码,只能使用普通的旧式JS和jQuery。
上下文:在一个网页上有几对输入,该对中的第一个输入在模糊时触发firstFunction()
,第二个输入也在模糊事件时触发secondFunction()
。从下面的示例代码中可以看到,每个函数然后调用另一个函数ajaxFunction()
,该函数执行AJAX请求。
目标:仅当先前的函数调用中没有其他AJAX请求正在进行时,我才希望能够调用ajaxFunction()
。事实是,当它第一次在一对输入上运行时,会在数据库中创建一个新行,并且请求返回该行的ID。因此,第二次调用时,由于ID的原因,它将是数据库中的UPDATE而不是INSERT。如果一对中的第二个调用在第一个调用完成之前运行,那么我最终将在数据库中有两个不同的行,这是不希望的。
[示例:如果用户在第一个输入中输入一些文本,则firstFunction()
在模糊时被触发,然后他迅速移至第二个输入并输入一些内容,因此secondFunction()
在模糊时被触发,但是可能是firstFunction()
调用的AJAX请求尚未完成的情况。因此,仅当来自secondFunction()
的AJAX调用已完成时,才应开始。当用户开始在第二个输入和第一个输入中输入内容时,这种逻辑也适用。
注意:这不是页面上唯一的AJAX请求,还有其他几个请求。
我已经进行了一些研究,我觉得firstFunction()
是我所需要的,但是在将其集成到此逻辑中时,它给我留下了深刻的印象。我也考虑过$.when()
,但实际上并没有帮助。
$.active
这是一种快速的排队方法,有多种方法可以使它更整洁,但这是基本概念
function firstFunction() {
// Some logic goes here then we call the AJAX function.
ajaxFunction(1, 2, 3);
}
function secondFunction() {
// Some logic goes here then we call the AJAX function.
ajaxFunction(4, 5, 6);
}
function ajaxFunction(param1, param2, param3) {
$.ajax({
method: "POST",
url: "https://website.localhost",
data: {
param1: param1
param2: param2
param3: param3
}
}).done(function() {
console.log('Done!');
});
}
由于您的示波器上有jQuery,因此我将使用队列功能来介绍此用例。其背后的基本思想是利用此可用功能并将您的XHR请求组织到FIFO行中。
[@ gnarf在function firstFunction() {
addToQueue({
param1: 1,
param1: 2,
param1: 3
});
}
function secondFunction() {
addToQueue({
param1: 1,
param1: 2,
param1: 3
});
}
var activeQueue = []
var activeRequest = false
function addToQueue(data) {
// Add item to the queue of things needing to run
activeQueue.push(data);
// if the request is not active than run it
if (!activeRequest) {
executeQueue()
}
}
function executeQueue() {
// if nothing to run, exit
if (!activeQueue.length) return
// set the request is active
activeRequest = true
// get the data for this request
var data = activeQueue.shift()
// make the call
$.ajax({
method: "POST",
url: "https://website.localhost",
data: data
}).done(function() {
console.log('Done!');
// mark call is done
activeRequest = activeQueue.length > 0
// run it again
executeQueue()
});
}
上很好地解释了。
如果您不想允许创建另一个ajax,如果已经在进行中并且尚未完成(错误或成功),则只需创建一个全局布尔变量,例如:
您可以在var ajaxInProgress = false
中将其设置为true,并在ajax完成时将其设置为false。然后,将ajax调用置于ajaxFunction
中。
这样,如果已经进行了一次,您将不会进行第二次ajax调用。
我怀疑您想将ajax调用排入队列,以便执行以下操作:
if(!ajaxInProgress) {...}
您的第二个函数将发送ajax,但仅在第一个函数完成后发送。为此,我将为您的代码编写一个简单的队列:
firstFunction();
secondFunction();