【问题标题】:Serial invocation of JS functionsJS函数的串行调用
【发布时间】:2014-08-24 02:35:07
【问题描述】:

这是我正在尝试做的(实际问题有所不同,但概述如下):

  1. 我有一个数组 [A..Z]。
  2. 对于上述数组中的每个字母,我有另一个数组:

    someArray[alphabet] = [1..100] //another array
    
  3. 对于 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 的同时执行)而不是其他方式。

我的步骤:

  1. 我能够按预期检索所有数据,但不是按顺序检索。

  2. 我尝试使用 flagssetInterval, clearInterval 来允许/禁止下一次迭代 - 它们没有按预期工作。

  3. 我也尝试过使用类似 - getAlphabets() && getNumbers() & getAnotherArray() 之类的东西,以为会按顺序执行,但我错了。

    李>

【问题讨论】:

  • 您是否必须对 3D 数组中的每个单元格进行单独的 ajax 调用,并且希望它们按顺序运行?这些数组是否已经存在并且您只想遍历它们为每个单元格进行 ajax 调用?还是在进行 ajax 调用时构建数组?
  • 我正在使用 ajax 调用构建数组。首先,我得到字母列表。然后,对于每个字母表,我调用 getNumbers(),对于 getNumbers() 返回的数组中的每个数字,我调用 getAnotherArray() -> 它传递适当的参数,获取相应的元素并从中构建一个数组。我可以一次完成所有这些,但我需要它们是连续的。

标签: javascript jquery arrays post


【解决方案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 调用一起使用绝不是一个好主意,因为它只会锁定浏览器。解决方案是以与异步调用一起使用的不同方式对迭代进行编码,而不是摆脱异步调用。
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多