Javascript,在回调函数之外的变量作用域?

时间:2021-09-17 20:09:29

everyone.

每一个人。

I have a problem about the 'callback function - scope of variable',

我有一个关于“回调函数-变量范围”的问题,

I wanna use the 'i in for loop' to 'the callback function User_UidSearch',

我想用I in for loop回调函数User_UidSearch,

but I cannot use it.

但我不能用它。

(I hope the solution don't use the global variable.)

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


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);
        }
    });
}

the "console.log(i);"

“console.log(i);“

Recheck, this is wrong. -> Outputs are "undefined" of all.

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

undefined is "console.log(result[i]);"

定义是“console.log(结果[我]);“

But the "i" is keep '2' console twice, if results.length is 2.

但是“i”是保持“2”控制台两次,如果结果。长度是2。

I know becuz the for loop ending then execute the User_UidSearch,

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

but how can I slove the it "i" is 0 and 1.

但是我怎么能把it I定义为0和1呢?

2 个解决方案

#1


1  

You're dealing with closures, rewrite your code as follows:

处理闭包时,重写代码如下:

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

I.e. wrap your function to unbind i.

即包装你的功能来解除我的束缚。

#2


3  

Your problem may be solved, but let me still add these points so others know the correct approach.

你的问题可能会得到解决,但我还是要补充这些观点,让其他人知道正确的方法。

Firstly, its not a good practice to call an asynchronous function inside a loop. This would lead to unexpected results.

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

Using closures is fine for some cases, but not this one. Read here for Practical uses of closures.

在某些情况下,使用闭包是可以的,但这一次不行。请阅读这里,了解闭包的实际用途。

There are several problems in the approach you've taken,

你采取的方法中有几个问题,

  1. If the results array is too long, there'll be a too many open requests.
  2. 如果结果数组太长,就会有太多的打开请求。
  3. callback(results) will be called before even a single callback of User_UidSearch is called.
  4. 回调(结果)将在调用User_UidSearch的单个回调之前被调用。

In your case, you should be using recursive function like this:

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

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);
        }
    });
}

Read this if interested detailed explaination of different control flows.

如果对不同控制流的详细解释感兴趣,请阅读本文。

#1


1  

You're dealing with closures, rewrite your code as follows:

处理闭包时,重写代码如下:

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

I.e. wrap your function to unbind i.

即包装你的功能来解除我的束缚。

#2


3  

Your problem may be solved, but let me still add these points so others know the correct approach.

你的问题可能会得到解决,但我还是要补充这些观点,让其他人知道正确的方法。

Firstly, its not a good practice to call an asynchronous function inside a loop. This would lead to unexpected results.

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

Using closures is fine for some cases, but not this one. Read here for Practical uses of closures.

在某些情况下,使用闭包是可以的,但这一次不行。请阅读这里,了解闭包的实际用途。

There are several problems in the approach you've taken,

你采取的方法中有几个问题,

  1. If the results array is too long, there'll be a too many open requests.
  2. 如果结果数组太长,就会有太多的打开请求。
  3. callback(results) will be called before even a single callback of User_UidSearch is called.
  4. 回调(结果)将在调用User_UidSearch的单个回调之前被调用。

In your case, you should be using recursive function like this:

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

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);
        }
    });
}

Read this if interested detailed explaination of different control flows.

如果对不同控制流的详细解释感兴趣,请阅读本文。