JavaScript / 使用回调保存变量值



我有以下带有Angular.js的代码:

$scope.createSSH = function(){
             for (var j=0; j<allGroupsArrays.length; j++){
                for (var i=0; i<$scope.appArray.length; i++){
                  allGroupsArrays[j][i][6] = Boolean(0);
                  allGroupsArrays[j][i][7] = Boolean(0);
                  // Some irrelvant code
                  WClient.createSSHK(allGroupsArrays[j][i][2], allGroupsArrays[j][i][3], allGroupsArrays[j][i][4], i, allGroupsArrays[j], allGroupsArrays[j][i][7], j).then(
              function(data) {
                    console.log("The j is: " + j)
                    console.log("The i is: " + i)
                  },
              function(message) {
                    console.log("Error")
                  }

当回调被备份时,我注意到ji变量值是笔记保存的。相反,它会打印以下内容:

The j is: 5
The i is: 3

即使在执行回调时,这些也是i为 0,j为 0。

如何保存变量的值上下文?

这是闭包的典型问题。循环执行,在它们完成值之后,ij当然是53的。但是then回调函数仍使用这些i,并从外部作用域j值。您需要做的是创建单独的范围值。

一种方法(至少有6种方法!)是使用函数Function.prototype.bind方法。它之所以有效,是因为它为ij创建具有作用域值的新函数:

WClient.createSSHK(allGroupsArrays[j][i][2], allGroupsArrays[j][i][3], allGroupsArrays[j][i][4], i, allGroupsArrays[j], allGroupsArrays[j][i][7], j).then(
    function(i, j, data) {
        console.log("The j is: " + j)
        console.log("The i is: " + i)
    }.bind(null, i, j),
    function(message) {
        console.log("Error")
    }.bind(null, i, j)
);

另请查看有关同一主题的这个非常受欢迎的问题。

调用回调函数时,ij 值取自父上下文,当它们递增时,值将始终是最后递增的(分别为53)。要解决此问题,必须传递要使用的当前值:

.then((function(i, j) {
    return function(data) {
        console.log("The j is: " + j)
        console.log("The i is: " + i)
    };
})(i, j))

在这里,你创建函数接收当前值(function(i, j) {...},立即(i, j)调用它)并使它们独立于父上下文。此函数返回要执行的函数 ( return function(data) {...} )。现在,您已经通过回调调用程序传递data并且i j createSSHK调用传递了值。

在循环中创建函数从来都不是一个好主意。尝试这样的事情:

$scope.createSSH = function(){
         for (var j=0; j<allGroupsArrays.length; j++){
            for (var i=0; i<$scope.appArray.length; i++){
              allGroupsArrays[j][i][6] = Boolean(0);
              allGroupsArrays[j][i][7] = Boolean(0);
              process(i ,j);
            }
         }
 function process(i, j){
              WClient.createSSHK(allGroupsArrays[j][i][2], allGroupsArrays[j][i][3], allGroupsArrays[j][i][4], i, allGroupsArrays[j], allGroupsArrays[j][i][7], j).then(
          function(data) {
                console.log("The j is: " + j)
                console.log("The i is: " + i)
              },
          function(message) {
                console.log("Error")
              }
 }

最新更新