1

我有以下代码:

for (var i = 0; i < numFiles; i++) {
    $.post('/Secure/File/PhysicalFileHandler.ashx?custId=whatever&idx=' + i, function (data) {
        ids += data + '|';
        if (i == numFiles-1) {
            ids = ids.substring(0, ids.length - 1);
        }
    });

}

在上一篇文章完成后,我怎么能执行一大块代码?我在上面尝试的方法不起作用(当i==到达numFiles那里时已经)。建议?

4

2 回答 2

2

这是一个有点常见的问题 - 您引用的“i”由 for 函数处理,并且通常在触发回调时 for 函数已经完成执行(在这种情况下,“i”已经等于 numFiles )。有几个解决方案:一个是将回调更改为:

(function (i) {
  return function (data) {
    ids += data + '|';
    if (i == numFiles-1) {
        ids = ids.substring(0, ids.length - 1);
    }
})(i)

这样做是为循环的每次执行创建一个新函数,并且每次函数都有自己对“i”的引用 - 而不是回顾 for 循环的 i 定义/值,它有自己的本地参数参考。这必须通过返回另一个函数来完成,因为您需要在 for 循环的第一次传递期间执行代码,确保在触发回调时保留正确的值。

另一种选择是将整个 post 语句包装在一个带有它自己的 i 副本的函数中 - 我认为两者之间没有太大区别。就个人而言,我更喜欢上面代码片段中的方法,因为它最大限度地减少了代码整体流程的影响,但对此意见会有所不同。

于 2013-01-05T01:39:33.097 回答
0

帖子可能不会按照开始的顺序完成。您必须在完成时数一数,才能知道所有内容都已完成。

var finishedCount = 0; // track number of calls finished
for (var i = 0; i < numFiles; i++) {
    (function(i) {
        $.post('/Secure/File/PhysicalFileHandler.ashx?custId=whatever&idx=' + i, function (data) {
            ids += data + '|';
            finishedCount = finishedCount + 1; // increment number of calls finished
            if (finishedCount == numFiles) { // run only when all calls have finished
                ids = ids.substring(0, ids.length - 1);
            }
        });
    })(i); // capture value of i in closure
}

编辑:不再需要在闭包中捕获 i 的值,因为在此版本的后回调函数中未使用 i。

于 2013-01-05T06:22:25.983 回答