Javascript,回调函数中的变量范围之外?

Posted

技术标签:

【中文标题】Javascript,回调函数中的变量范围之外?【英文标题】:Javascript, outside variable scope in callback function? 【发布时间】:2014-10-06 11:52:30 【问题描述】:

每个人。

我对“回调函数 - 变量范围”有疑问,

我想使用'i in for loop'到'回调函数User_UidSearch',

但我不能使用它。

(我希望解决方案不要使用全局变量。)


Task_TidSearchExecution = function(tid, callback) 
    var sql = "SELECT * FROM execution WHERE task = '" + tid + "'";
    dbclient.query(sql, function (err, results) 
        if (err || results.length <= 0)
            callback(false);
        else 
            console.log(results.length);
            for (var i = 0 ; i < results.length ; i++) 
                User_UidSearch(results[i].employee, function (user) 
                    console.log(i);
                    // results[i]['email'] = user.email;
                );
            

            callback(results);
        
    );

“console.log(i);”

重新检查,这是错误的。 -> 输出是“未定义的”。

未定义是“console.log(result[i]);”

但如果 results.length 为 2,“i”将保持 '2' 控制台两次。

我知道因为 for 循环结束然后执行 User_UidSearch,

但我如何才能解决它“i”是 0 和 1。

【问题讨论】:

不,不是。它在外部function 本地范围内定义。但它用于闭包,需要特殊的逻辑才能工作。 @Salmon - 你确定console.log(i) 写的是undefined 而不是results.length 的值吗? @BOSS 我很想看到一个小提琴来证明这一点。 "输出都是 'undefined' of all" 并不真正适合所提供的 sn-p。 i 至少应该是一个数字,只是可能不是预期的特定值。如果每条日志都显示results.length的值,那么请看:javascript closure inside loops – simple practical example。 将 user_UidSearch 调用封装在一个闭包中,传入 i 和 results @IlyaLuzyanin: rigt.my bad I didn't see through clear.removed my comment 【参考方案1】:

你的问题可能已经解决了,但还是让我补充一下这些点,以便其他人知道正确的方法。

首先,在循环中调用异步函数不是一个好习惯。这会导致意想不到的结果。

在某些情况下使用闭包很好,但不是这种情况。在这里阅读Practical uses of closures。

您采取的方法存在几个问题,

    如果结果数组太长,将会有太多打开的请求。 callback(results) 将在调用 User_UidSearch 的单个回调之前被调用。

在你的情况下,你应该使用这样的递归函数:

var len = results.length;
var count = 0;
function my_func() 
    User_UidSearch(results[count].employee, function (user) 
        console.log(count);
        // results[count]['email'] = user.email;

        count += 1;
        if (count < len) 
            my_func();
         else 
            callback(results);
        
    );

如果有兴趣了解不同控制流的详细说明,请阅读this。

【讨论】:

是的,你是对的。我已经解决了你的说法。但是你的解决方案比我的好,非常感谢:)【参考方案2】:

你正在处理closures,重写你的代码如下:

...
(function(id) 
    User_UidSearch(results[id].employee, function (user) 
        console.log(id);
        // results[i]['email'] = user.email;
    );
)(i);

即包装您的函数以取消绑定i

【讨论】:

非常感谢,我按照这个方法解决。 不客气!如果你知道如何正确使用闭包,它们就是很棒的东西!

以上是关于Javascript,回调函数中的变量范围之外?的主要内容,如果未能解决你的问题,请参考以下文章

如何在javascript中访问当前范围之外的变量?

JavaScript 回调函数属于闭包?

从javascript中的回调获取数据?

理解JavaScript中的回调函数

Javascript命名空间 - 如何根据命名导出函数范围内定义的函数和变量?

将范围传递给回调函数/绑定