不使用 'async: false' 进行顺序 $.getjson 调用的替代方法

Posted

技术标签:

【中文标题】不使用 \'async: false\' 进行顺序 $.getjson 调用的替代方法【英文标题】:alternative for not using 'async: false' for a sequential $.getjson call不使用 'async: false' 进行顺序 $.getjson 调用的替代方法 【发布时间】:2021-11-19 13:07:33 【问题描述】:

更新:重写问题以突出我的预期结果

我想做的事:

    通过顺序 json 链接循环到一个数组 --- 从 1.json 到 100.json 在 arr[n][0] 中添加 # 以存储 n.json # --- arr[0][0] = 1 for 1.json, arr[1][0] = 2 for 2.json 找到最长的数组并通过 $.getjson 获取它的头部 --- 所以我必须先完成 arr[] 捕获 根据信息显示决赛桌。我是从第 2 步和第 3 步得到的。

即第一个:getjson1 -> 第二个:找到最长的数组和getjson2 -> 第三个:showtable

这可以通过使用 async: false 来完成,但是性能很差。我正在寻找获得相同结果的替代方法。


没有'async: false',问题是:

加载 arr[] 比第 3 步和第 4 步花费更长的时间 未能将1标记到arr[0]存储1.json数据的array[0][0]中 我可以将7.json数据存入arr[0],但需要确保arr[0][0] = 7

预期结果

读取 1.json -> 先将 '1' 写入 arr[0][0] -> 将 1.json 数据写入 arr[0][1], arr[0][2] 读取 2.json -> 先将 '2' 写入 arr[1][0] -> 将 2.json 数据写入 arr[1][1], arr[1][2], arr[1][3]

有问题的结果:将 7.json 数据写入 arr[0] 并将 arr[0][0] 标记为 '1',我怀疑它基于哪个 .json 先完成

先将'1'写入arr[0][0]---->将7.json数据推入arr[0][1],arr[0][2],arr[0][3] 先将'2'写入arr[1][0]---->将6.json数据推入arr[1][1],arr[1][2]


【问题讨论】:

【参考方案1】:

更新的答案,按顺序运行每个 AJAX:

我以为您想同时运行所有 AJAX 操作并且只进行一次后续操作,但从 cmets 听起来您想单独等待每个 AJAX 操作。当然,您只是不希望它们被阻止。

由于我们正在处理 Promise 接口,您仍然可以await 它。仍然从函数返回Promise

function readdata(i) 
  return $.getJSON(
    // no changes here
  )

但是现在,不是将每个都添加到数组中,而是 await 每个。并在async IIFE 中完成所有这些操作,这样您就可以使用await 关键字。由于每个都在等待,因此您只需在之后运行后续操作。例如:

(async function () 
  for (var i = 1; i <= 10; i++) 
    await readdata(i);
  
  showtable();
)();

这与您之前的“async: false”方法的效果相似,因为每个操作都必须在下一个操作继续之前完成。但主要区别在于这种方法不会阻塞 UI,因此用户感觉不到效果。


原始答案,同时运行所有 AJAX:

我认为 jQuery 的 AJAX 操作返回一个 Promise 接口,所以它们应该是可等待的。如果是这种情况,请从 readdata 返回该 Promise:

function readdata(i) 
  return $.getJSON(
    // no changes here
  )

然后在循环中调用该函数时,将返回的 Promises 添加到数组中:

var promises = [];
for (var i = 1; i <= 10; i++) 
  promises.push(readdata(i));

现在你有了一个 Promise 数组,你可以等待它们全部完成后再继续:

Promise.all(promises).then(function () 
  showtable();
);

这里的好处是您不会单独阻止每个 AJAX 操作,甚至不会单独等待每个 AJAX 操作。它们都立即触发并在浏览器可以管理的情况下同时运行。在所有这些都完成之前,您只是不运行后续操作。

【讨论】:

谢谢大卫。它看起来几乎可以解决我的问题,但我只是尝试过,它没有正确地将 1.json 读入 arr[0] (可能将最早完成的 getjson 推入 [0]),任何解决此问题的方法。此外,我稍微编辑了问题以添加 1 个步骤。 @ChanTaiMan:“它没有将 1.json 正确读入 arr[0]”具体是什么意思?是否发出了 AJAX 请求?反应是你所期望的吗?当您在浏览器的调试器中单步执行代码时,具体会发生什么?这与您在问题中所问的问题不同吗? 抱歉没有说清楚。我想从0到10同步读取数据。读取1.json->先将'1'写入arr[0][0]->将1.json数据写入arr[0][1],arr[0] [2], arr[0][3] 读取 2.json -> 先将 '2' 写入 arr[1][0] -> 将 2.json 数据写入 arr[1][1], arr[1] [2], arr[1][3] 但现在有了你的解决方案,以随机顺序读取的数据可能 7.json 最容易完成。先将'1'写入arr[0][0]---->将7.json数据推入arr[0][1],arr[0][2],arr[0][3]写入'2 ' into arr[1][0] first ----> push 6.json data into arr[1][1], arr[1][2], arr[1][3] @ChanTaiMan:哦,所以你希望操作总是一个接一个地运行,而不是同时运行? @ChanTaiMan:我已经用完全顺序的版本更新了答案。

以上是关于不使用 'async: false' 进行顺序 $.getjson 调用的替代方法的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot @Async实现异步调用

async/await 函数不等待。多个功能不按顺序运行和完成

[转]多个ajax请求时控制执行顺序或全部执行后的操作

jQuery.ajax为啥不能实现return值

MongoDB 使用 Async.js 与 $in 保持顺序 [重复]

MongoDB 使用 Async.js 与 $in 保持顺序 [重复]