JS函数的串行调用
Posted
技术标签:
【中文标题】JS函数的串行调用【英文标题】:Serial invocation of JS functions 【发布时间】:2014-08-24 02:35:07 【问题描述】:这是我正在尝试做的(实际问题有所不同,但概述如下):
-
我有一个数组 [A..Z]。
对于上述数组中的每个字母,我有另一个数组:
someArray[alphabet] = [1..100] //another array
对于 someArray[alphabet] 中的每个数字,还有另一个数组:
anotherArray[number] = [a..z,A..Z,1..1000]
假设对于每个 alphabet,我获取 someArray[alphabet],并且对于 someArray[alphabet] 中的每个 number /strong>,我从服务器获取 anotherArray[number] - 这需要时间。
此外,获取它们的函数如下 - 我进行 jQuery post 调用以从服务器获取数据。我需要按顺序执行它们。
getAlphabets()
//I get them here
//For Each alpha, I call:
getNumbers(alpha);
getNumbers(alpha)
//I get someArray here.
//For Each element in someArray
//getAnotherArray(element)
getAnotherArray(number)
//I get them here
//For Each element in anotherArray
//get all [a..z,A..Z,1..1000]
//display them
问题是 getNumbers(alpha) 的迭代没有等待 getAnotherArray(previousIteration) 完成。执行(函数调用并行运行(A..Z 的同时执行)而不是其他方式。
我的步骤:
我能够按预期检索所有数据,但不是按顺序检索。
我尝试使用 flags 和 setInterval, clearInterval 来允许/禁止下一次迭代 - 它们没有按预期工作。
我也尝试过使用类似 - getAlphabets() && getNumbers() & getAnotherArray() 之类的东西,以为会按顺序执行,但我错了。
李>【问题讨论】:
您是否必须对 3D 数组中的每个单元格进行单独的 ajax 调用,并且希望它们按顺序运行?这些数组是否已经存在并且您只想遍历它们为每个单元格进行 ajax 调用?还是在进行 ajax 调用时构建数组? 我正在使用 ajax 调用构建数组。首先,我得到字母列表。然后,对于每个字母表,我调用 getNumbers(),对于 getNumbers() 返回的数组中的每个数字,我调用 getAnotherArray() -> 它传递适当的参数,获取相应的元素并从中构建一个数组。我可以一次完成所有这些,但我需要它们是连续的。 【参考方案1】:当您进行 ajax 调用等异步操作时,要按顺序迭代某些数据结构,您必须使用不同形式的迭代。您不能使用常规的 for
循环或 while
循环。相反,您创建一个函数来进行迭代。您创建一个状态变量来跟踪您在迭代中的位置。您启动了一个 Ajax 调用。当它返回时,您处理结果,然后启动下一个 ajax 调用(随时更新迭代状态)。
这是一个例子:
假设你有一个任意长度的数组:
var theData = [...];
而且,您希望对该数组中的每个项目进行 ajax 调用,并将结果收集到另一个数组中。出于特定原因,您希望强制 Ajax 调用按顺序进行,以便仅在第一次调用完成后进行第二次调用,依此类推。
function processArray(data)
var def = $.Deferred();
var currentItem = 0;
var results = [];
function next()
if (currentItem < data.length)
$.ajax(...).done(function(result)
// process the result here
results.push(result);
// advance the counter and start the next Ajax call
++currentItem;
next();
).fail(function(jqXHR, textStatus, errorThrown)
def.reject(jqXHR, textStatus, errorThrown);
);
else
def.resolve(results);
next();
return def.promise();
// call it like this
processArray(theData).done(function(results)
// do something with the results array here
);
现在,如果您有三个维度的迭代状态,那么跟踪状态会稍微复杂一些(您将拥有三个版本的 currentItem 来跟踪您在三个维度中的每一个维度中的位置),但它否则可能与完成一个维度时增加的复杂性相似的逻辑,您需要换行到下一行并重新开始。
【讨论】:
感谢您的更新。请给我一些时间来理解代码。【参考方案2】:当您使用 ajax 来获取数据时,请求不会按顺序执行,因为 ajax 是一个异步函数。您需要关闭async
。所以,它会按照你想要的顺序运行。
async: false
异步(默认:true)类型:布尔值 默认情况下,所有请求都是异步发送的(即默认设置为 true)。如果您需要同步请求,请将此选项设置为 false。跨域请求和 dataType: "jsonp" 请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作。
示例:
jQuery.ajax(
url: strUrl,
success: function(html)
strReturn = html;
,
async:false
);
【讨论】:
将async: false
与ajax 调用一起使用绝不是一个好主意,因为它只会锁定浏览器。解决方案是以与异步调用一起使用的不同方式对迭代进行编码,而不是摆脱异步调用。以上是关于JS函数的串行调用的主要内容,如果未能解决你的问题,请参考以下文章