【问题标题】:Elegantly pass down variable to asynchronous callback优雅地将变量传递给异步回调
【发布时间】:2014-10-03 12:04:52
【问题描述】:

我正在编写一段代码来从 DB 构建模式,并基于 SE 上的其他示例,我想出了这种方法将表名一直传递到我将处理表字段的代码(我当时需要访问表名)。架构来自 MySQL,使用 jugglingdb-mysql。

这是我能做的最“优雅”的事情吗(我不希望代码中像现在这样写闭包)?

schema.client.query('SHOW TABLES', function(err, data) {
    if (err) throw err;
    data.forEach(function(table) {
        // closure to pass down table name
        (function(_table) {
            schema.client.query('SHOW columns FROM ' + _table, function(err, rows) {
                if (err) throw err;
                // closure to pass down table name
                (function(_table) {
                    rows.forEach(function(row){
                        // Go wild processing fields
                    })
                })(_table);
            });
        })(table['Tables_in_db'])
    });
});

【问题讨论】:

    标签: javascript mysql node.js closures


    【解决方案1】:

    内部函数从外部函数继承变量。在这种情况下,您不需要那么麻烦来传递变量,以下内容就足够了:

    data.forEach(function(table) {
        var _table = table['Tables_in_db'];
        schema.client.query('SHOW columns FROM ' + _table, function(err, rows) {
            if (err) throw err;
            rows.forEach(function(row){
                // Go wild processing fields
            })
        });
    });
    

    您唯一需要对立即调用的函数执行该技巧的时候是在创建callbacks inside for-loops 时。由于 Javascript 范围是基于函数而不是基于块的,因此 for 循环不会引入新的范围,并且迭代变量最终会被所有回调共享(最终将指向最后一个元素)。

    【讨论】:

    • 确实,您的代码按预期工作,即使之前认为与您的代码类似的东西对我不起作用。我一定是在错误的地方完成了我的任务。
    • 您使用的是普通的 for 或 while 循环而不是 forEach 方法吗?
    • 是的,我开始使用 for 循环,然后才意识到使用 forEach 更简单,只是认为我不应该摆脱闭包。
    • 当时可能就是这样。 forEach 的回调已经是一个正在创建新范围的闭包 - 现在不需要额外的 :)
    猜你喜欢
    • 2022-10-04
    • 2012-10-24
    • 2020-08-07
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    相关资源
    最近更新 更多