循环中存在异步的情况
循环中存在异步的情况
1 for (var i=0, l=arr.length; i<l; i++) { 2 var sql = "select * from nx_user"; 3 db.query(sql, function(){ 4 sys.log(i + ': ' + sql); 5 }); //db.query为表查询操作,是异步操作 6 }
你会发现,输出的结果都是相同的,而且是当i=arr.length-1时的输出内容。因为JavaScript是单线程的,它会先执行完整个循环的同步内容之后,才去执行其中的异步操作。代码中的匿名回调函数就是一个异步回调。执行到该函数的时候,for循环以及后面的一些同步操作都已经执行完毕。出于闭包原则,该函数会保留for循环的最后一次循环的sql变量和i变量的内容,所以才会导致错误的结果。
那怎么办呢?解决方法有两种,一种是使用立即函数,如下:
1 for (var i=0, l=arr.length; i<l; i++) { 2 var sql = "select * from nx_user"; 3 (function(sql, i){ 4 db.query(sql, function(){ 5 sys.log(i + ': ' + sql); 6 }); //db.query为表查询操作,是异步操作 7 })(sql, i); 8 }
还有一种方法是将异步操作部分提取出来,单写一个函数,如下:
1 var outputSQL = function(sql, i){ 2 db.query(sql, function(){ 3 sys.log(i + ': ' + sql); 4 }); //db.query为表查询操作,是异步操作 5 } 6 7 for (var i=0, l=arr.length; i<l; i++) { 8 var sql = "select * from nx_user"; 9 outputSQL(sql, i); 10 } 11