这几天跟着视频学习node.js,碰到不少的异步函数的问题,如今将for循环中出现的异步函数回调值的问题总结以下:javascript
具体问题是关于遍历文件夹中的子文件夹的,for循环包裹异步函数的代码:前端
for (var i = 0; i < files.length; i++) { var itemFile = files[i]; fs.stat("./uploads/" + itemFile, function (err, stats) { if (stats.isDirectory()) { console.log(itemFile+i); } else { console.log(2); } }); }
输出结果是:java
wedding3 wedding3 wedding3
for循环是同步任务,i在不断滴增长直到等于file.length时候,循环再也不执行,即等于3(本身实验代码)。而循环内部的判断是不是文件夹的isDirectory函数是异步函数,也就是说内部的console.log(itemFile+i); 的执行任务被排在了任务队列的最后,因此for循环自己会先执行3次,可是不执行回调里面的任务,for循环都结束时,回调函数里面的console.log才开始执行第一次,因此每次输出都是wedding3.node
固然这并非咱们想要的结果,解决方法能够经过自执行函数传参(匿名函数),这样就造成了不受外界变量影响的局部做用域。如:jquery
for (var i = 0; i < files.length; i++) { (function(i){ var itemFile = files[i]; fs.stat("./uploads/" + itemFile, function (err, stats) { if (stats.isDirectory()) { console.log(itemFile+i); } else { console.log(2); } }); })(i); }
输出获得:异步
cat0 dog1 wedding2
这样就能够解决以前只输出最后循环的值的问题。函数
前端页面开发也会碰到相似的问题,好比setTimeout异步执行的问题,在前端能够经过jquery的each方案解决。用jQuery的 $.each(),自带回调函数,造成了函数做用域.学习
<script type="text/javascript"> var arr = ["dog",cat","wedding"]; $.each(arr, function(key, value) { setTimeout(function() { console.log(key); console.log(value); }, 2000); }); </script>