所以一切正常,问题是如果发现冲突它会调用showInstConflicts(allconflicts, joined);
两次...调试显示它评估为真两次但我无法弄清楚它是如何可能的。如果没有冲突,则不会两次调用generatePDF()
函数。
我正在使用的表单会根据教师现有的时间表检查建议的时间表(我们所使用的表格),以查看是否存在冲突。有时,教师可以为一个班级设置多个会议时间,如:
在这种情况下,ajax检查需要运行两次以确保两次会议时间没有冲突。
循环计算找到nodata
的次数,检查是否检查了它是否足够(joined.length
这是要检查的会议时间数组)以及是否至少有一次收到数据(即冲突)的时间。如果它找到至少一个success
调用,它会调用显示冲突的显示函数showInstConflicts()
,在所有检查完成后(i==times
)。
如果nodata
计数
我正在使用个人jQuery插件.JSONTable()
,只需进行$.ajax
调用,并根据已定义的设置将其格式化为表格。当ajax返回nodata:
时会调用data.length < 1
。
所以这是循环:
var times = joined.length;
var nodata = 0;
var allconflicts = $('<div></div>');
for (i = 0; i < times; i++) {
var conflicts = $('<div></div>').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,文件的后半部分。
答案 0 :(得分:2)
因此,看起来JSONTable是一个Ajax调用。这意味着它是异步的。因此,您的for
循环将立即启动所有异步调用,并且索引i
将在第一个循环结束时处于循环结束时的值。此外,您的Ajax调用可以按任意顺序完成。
如果要查看与该特定Ajax调用相对应的i
的正确值,那么您必须将i
放入闭包中,以便为每个Ajax保留唯一调用
如果您希望Ajax调用按严格的顺序执行,那么您必须重新调整运行方式(不能使用直接for
循环)。
以下是如何为每个单独的ajax调用保留i
的值:
var times = joined.length;
var nodata = 0;
var allconflicts = $('<div></div>');
for (var i = 0; i < times; i++) {
// create closure to capture the value of i
(function(i) {
var conflicts = $('<div></div>').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调用后将其传递给数组中的回调(可能使用{{1} })。