Javascript 关闭不起作用 [英] Javascript closure not working

查看:31
本文介绍了Javascript 关闭不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了这些问题:

I've read these questions:

并尝试应用他们的解决方案(以及至少 1/2 的其他实现),但都没有奏效.

and tried to apply their solutions (as well as at least 1/2 a dozen other implementations) and none of them are working.

这是具有循环的函数:

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] 将另一个引用注入到这个文件中,它会导致循环引用,代码将无法运行)

And here's the errorLogging function that is writing my message (Note, I'm not able to "write" the message in the same javascript file because I'd need to [angular] inject another reference into this file and it would cause a circular reference and the code won't run)

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

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

What other method can I implement to stop it from returning the very last "id" of my sync records (when it's only the first record that has the error)?

推荐答案

… var i …
async(function() { …
//  errorLogging(tx, error, id);
    (function(a, b, c) {
        errorLogging(a, b, idsArray[c]);
    })(tx, error, i);
… })

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

That's rather useless, because the i variable already does have the wrong values there. You need to put the wrapper around the whole async callback, closing over all variables are used within the async callback but are going to be modified by the synchronous loop.

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

The easiest way (works always) is to simply wrap the complete loop body, and close over the iteration variable:

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

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

You also might pass all variables that are constructed in the loop (and depend on the iteration variable) as the closure arguments. In your case, it might look like this:

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
}

或者你确定异步回调,然后只包装它:

Or you identify the async callback, and wrap only that:

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
}

这篇关于Javascript 关闭不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆