JavaScript 变量在异步回调中更改

javascript variable changed in async callback

本文关键字:回调 异步 变量 JavaScript      更新时间:2023-09-26
  a = ["1","2","3"]
  square = (i,cb)->
    i = parseInt(i)
    setTimeout ()->cb null,i*i,100
  for i in a
    square i,(err,result)->
      console.log i + " " + result
    output:
    3 1
    3 4
    3 9
    expected:
    1 1
    2 4
    3 9

如果删除设置超时,我可以得到预期的结果。

或者这样写

    for i in a
      ((i)->
        square i,(err,result)->
          console.log i + " " + result
      )(i)

这是一个JavaScript错误吗?

这是实际 javascript 中的相同代码,产生相同的结果(和小提琴:http://jsfiddle.net/99obrntp/(

var a = ['1','2','3'];
function square(i, cb){
    i = parseInt(i);
    setTimeout(function(){
        cb(null, i*i);
    }, 100);
}
for(var i=0; i<a.length; i++){
    var value = a[i];
    square(value, function(err, result){
        console.log(value, result);
    });
}

现在平方结果显然是正确的,但问题是你对console.log()的调用。原因是在循环完成之前不会第一次调用回调(因为 setTimeout (。换句话说,value在首次写入控制台之前变得3。要解决此问题,您需要将值传递给回调。例如:

var a = ['1','2','3'];
function square(i, cb){
    i = parseInt(i);
    setTimeout(function(){
        cb(null, i*i, i);
    }, 100);
}
for(var i=0; i<a.length; i++){
    var value = a[i];
    square(value, function(err, result, initial){
        console.log(initial, result);
    });
}

更新小提琴:http://jsfiddle.net/3sdjgzv1/