为什么多个ajax查询循环运行成功两次?

所以一切正常,问题是如果发现冲突它调用showInstConflicts(allconflicts, joined); 两次…调试显示它评估为真两次,但我无法弄清楚它是如何可能的。 当没有冲突时,它不会两次调用generatePDF()函数。

我正在使用的表单会根据教师现有的时间表检查建议的时间表(我们所使用的表格),以查看是否存在冲突。 有时,教师可以为一个class级设置多个会议时间,例如:

  1. MWF,1730-1930,1月12日 – 5月5日,BLDG ROOM
  2. TR,1200-0100,1月12日 – 5月5日,BLDG ROOM2

在这种情况下,ajax检查需要运行两次以确保两次会议时间没有冲突。

循环计算找到nodata的次数,检查它是否被检查了足够的次数( joined.length这是一个要检查的会议时间数组)以及是否至少有一次收到数据(也就是冲突) 。 如果它找到至少一个success调用它会调用显示函数showInstConflicts() ,它会在所有检查完成后显示冲突( i==times )。

如果nodata计数

我正在使用个人jQuery插件.JSONTable() ,它只是进行$.ajax调用,并根据定义的设置将其格式化为表格。 当ajax返回data.length < 1时,将调用nodata: .

所以这是循环:

 var times = joined.length; var nodata = 0; var allconflicts = $('
'); for (i = 0; i < times; i++) { var conflicts = $('
').appendTo(allconflicts); //use $.JSONTable plugin (see plugins.js) to check instructor conflicts conflicts.JSONTable({ url: '/ajax/ajaxCSFInstCheck.php', options: joined[i], noWraps: ['allrows'], columns: ['Name', 'Primary', 'Responsible', 'CRN', 'Class', 'Dates', 'Days', 'Times', 'Location', 'XST', 'Web', 'All Meetings'], responsive: true, success: function () { //if conflicts found, show on the final ajax return //*** this is evaluating true twice per run *** if (i == times && nodata < times) { showInstConflicts(allconflicts, joined); } }, nodata: function () { //if no conflicts found, make the PDF nodata++; if (i == times && nodata == times) { generatePDF(); } } }); }

$.fn.JSONTable的代码在我的网站http://curric.uaa.alaska.edu/js/plugins.js上 ,该文件的后半部分。

因此,看起来JSONTable是一个Ajax调用。 这意味着它是异步的。 因此,你的for循环将立即启动所有异步调用,并且当第一个完成时,索引i将处于循环结束时的值。 此外,您的Ajax调用可以按任意顺序完成。

如果你想看到对应于特定Ajax调用的i的正确值,那么你必须将i放入一个闭包中,以便为每个Ajax调用保留唯一的。

如果您希望Ajax调用按严格的顺序执行,那么您将不得不重新for它们的运行方式(您不能使用直接for循环)。

以下是为每个单独的ajax调用保留i值的方法:

 var times = joined.length; var nodata = 0; var allconflicts = $('
'); for (var i = 0; i < times; i++) { // create closure to capture the value of i (function(i) { var conflicts = $('
').appendTo(allconflicts); //use $.JSONTable plugin (see plugins.js) to check instructor conflicts conflicts.JSONTable({ url: '/ajax/ajaxCSFInstCheck.php', options: joined[i], noWraps: ['allrows'], columns: ['Name', 'Primary', 'Responsible', 'CRN', 'Class', 'Dates', 'Days', 'Times', 'Location', 'XST', 'Web', 'All Meetings'], responsive: true, success: function () { //if conflicts found, show on the final ajax return //*** this is evaluating true twice per run *** if (i == times && nodata < times) { showInstConflicts(allconflicts, joined); } }, nodata: function () { //if no conflicts found, make the PDF nodata++; if (i == times && nodata == times) { generatePDF(); } } }); })(i); }

我很难跟踪你是如何处理所有这些数据的。 通常,如果您要检索N个异步数据,并且您想对此数据执行的某些操作需要查看多个异步结果,那么最简单的方法是收集所有数据(通常是数组)然后当您拥有所有数据时,最后一次处理所有结果。 然后,可以一次查看任何结果间依赖关系。

当使用多个ajax调用执行此操作时,通常最简单的方法是使用promises并让promises基础结构收集所有结果,并在完成所有ajax调用(可能使用Promise.all() )时将其传递给数组中的回调。