【问题标题】:Javascript closure not workingJavascript关闭不起作用
【发布时间】:2014-10-05 16:13:38
【问题描述】:

我已经阅读了这些问题:

并尝试应用他们的解决方案(以及至少 1/2 十几个其他实现),但没有一个有效。

这是有循环的函数:

ExecuteQueryWhereQueryAndParamsBothArrays: function (queryArray, paramsArray, idsArray, success, fail, errorLogging) {
            var hasError = false;
            $rootScope.syncDownloadCount = 0;
            $rootScope.duplicateRecordCount = 0;

            $rootScope.db.transaction(function (tx) {
                for (var i = 0; i < paramsArray.length; i++) {
                    window.logger.logIt("id: " + idsArray[i]);

                    var query = queryArray[i];
                    var params = paramsArray[i];
                    var id = idsArray[i];

                    tx.executeSql(query, params, function (tx, results) {
                        incrementSyncDownloadCount(results.rowsAffected);
                    }, function(tx, error) {
                        if (error.message.indexOf("are not unique") > 0 || error.message.indexOf("is not unique") > 0) {
                            incrementDuplicateRecordCount(1);
                            return false;
                        }

// this didn't work:    errorLogging(tx, error, id);
// so I wrapped in in an IIFE as suggested:
                        (function(a, b, c) {
                            errorLogging(a, b, idsArray[c]);
                        })(tx, error, i);

                        return true;
                    });
                }
            }, function () {
                fail();
            }, function () {
                success();
            });

这是正在写入我的消息的 errorLogging 函数(注意,我无法在同一个 javascript 文件中“写入”消息,因为我需要 [angular] 向该文件中注入另一个引用,它会导致循环引用,代码不会运行)

var onError = function (tx, e, syncQueueId) {
    mlog.LogSync("DBService/SQLite Error: " + e.message, "ERROR", syncQueueId);
};

我可以实施什么其他方法来阻止它返回我的同步记录的最后一个“id”(当它只是第一个有错误的记录时)?

【问题讨论】:

  • 哎呀,谢谢你关闭这个。但是您引用的那个确切的已经尝试过并且不起作用。
  • 我应该将链接指向我尝试过的所有其他实现吗?
  • 否,但您可能已经更清楚地表明您已经尝试应用您找到的解决方案。我需要再次查看代码以查看关闭尝试,仅由注释掉的旧版本突出显示。回想起来,这实际上是一个很好的问题。

标签: javascript loops closures


【解决方案1】:
… var i …
async(function() { …
//  errorLogging(tx, error, id);
    (function(a, b, c) {
        errorLogging(a, b, idsArray[c]);
    })(tx, error, i);
… })

这没什么用,因为i 变量已经在那里有错误的值。您需要将包装器放在整个异步回调周围,关闭异步回调中使用但将由同步循环修改的所有变量。

最简单的方法(总是有效)是简单地包装完整的循环体,并关闭迭代变量:

for (var i = 0; i < paramsArray.length; i++) (function(i) { // here
    var query = queryArray[i];
    var params = paramsArray[i];
    var id = idsArray[i];

    window.logger.logIt("id: " + id);
    tx.executeSql(query, params, function (tx, results) {
        incrementSyncDownloadCount(results.rowsAffected);
    }, function(tx, error) {
        if (error.message.indexOf("are not unique") > 0 || error.message.indexOf("is not unique") > 0) {
            incrementDuplicateRecordCount(1);
            return false;
        }
        errorLogging(tx, error, id);
        return true;
    });
}(i)); // and here

您还可以将循环中构造的所有变量(并依赖于迭代变量)作为闭包参数传​​递。在您的情况下,它可能如下所示:

for (var i = 0; i < paramsArray.length; i++) {
    (function(query, params, id) { // here
        window.logger.logIt("id: " + id);
        tx.executeSql(query, params, function (tx, results) {
            incrementSyncDownloadCount(results.rowsAffected);
        }, function(tx, error) {
            if (error.message.indexOf("are not unique") > 0 || error.message.indexOf("is not unique") > 0) {
                incrementDuplicateRecordCount(1);
                return false;
            }
            errorLogging(tx, error, id);
            return true;
        });
    }(queryArray[i], paramsArray[i], idsArray[i])); // here
}

或者您识别异步回调,并仅包装它:

for (var i = 0; i < paramsArray.length; i++) {
    window.logger.logIt("id: " + idsArray[i]);
    tx.executeSql(queryArray[i], paramsArray[i], function (tx, results) {
        incrementSyncDownloadCount(results.rowsAffected);
    }, (function(id) { // here
        return function(tx, error) {
//      ^^^^^^ and here
            if (error.message.indexOf("are not unique") > 0 || error.message.indexOf("is not unique") > 0) {
                incrementDuplicateRecordCount(1);
                return false;
            }
            errorLogging(tx, error, id);
            return true;
        };
    }(idsArray[i]))); // and here
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多