我有以下带有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")
}
当回调被备份时,我注意到j
和i
变量值是笔记保存的。相反,它会打印以下内容:
The j is: 5
The i is: 3
即使在执行回调时,这些也是i
为 0,j
为 0。
如何保存变量的值上下文?
这是闭包的典型问题。循环执行,在它们完成值之后,i
和j
当然是5
和3
的。但是then
回调函数仍使用这些i
,并从外部作用域j
值。您需要做的是创建单独的范围值。
一种方法(至少有6种方法!)是使用函数Function.prototype.bind
方法。它之所以有效,是因为它为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(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)
);
另请查看有关同一主题的这个非常受欢迎的问题。
调用回调函数时,i
和 j
值取自父上下文,当它们递增时,值将始终是最后递增的(分别为5
和3
)。要解决此问题,必须传递要使用的当前值:
.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")
}
}