2015-12-10 115 views
0
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 

如果删除setTimeout我可以得到预期的结果。javascript变量异步回调

或写这样

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

这是一个JavaScript错误?

+0

这是一个JavaScript代码?你可以创建一个小提琴http://jsfiddle.net? – gurvinder372

+0

那是什么? CoffeeScript,Typescript?这不是JavaScript。 – Andy

+0

该输出不是一个错误,它的异步工作方式。当您的超时呼叫被触发时,for循环已经完成。所以'i'保存循环中使用的最后一个值,在这种情况下是3,所以每次输出3。 –

回答

0

下面是相同的代码,在实际的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/