这几天跟着视频学习node.js,碰到很多的异步函数的问题,现在将for循环中出现的异步函数回调值的问题总结如下:

具体问题是关于遍历文件夹中的子文件夹的,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);
}
});
}

输出结果是:

wedding3
wedding3
wedding3

for循环是同步任务,i在不断滴增加直到等于file.length时候,循环不再执行,即等于3(自己实验代码)。而循环内部的判断是否是文件夹的isDirectory函数是异步函数,也就是说内部的console.log(itemFile+i); 的执行任务被排在了任务队列的最后,所以for循环本身会先执行3次,但是不执行回调里面的任务,for循环都结束时,回调函数里面的console.log才开始执行第一次,所以每次输出都是wedding3.

当然这并不是我们想要的结果,解决方法可以通过自执行函数传参(匿名函数),这样就形成了不受外界变量影响的局部作用域。如:

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>

js的for循环中出现异步函数,回调引用的循环值总是最后一步的值?的更多相关文章

  1. js的for循环中出现异步函数,回调引用的循环值始终是最后的值

    一.问题 今天工作中解决bug发现是由“for循环的异步函数,回调引用的循环值始终是最后的值”的现象导致的,如: for (var i = 0; i < files.length; i++) { ...

  2. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

  3. JS循环中使用bind函数的参数传递问题

    JS循环中使用bind函数的参数传递问题,问题代码如下: for (var sc in result) { var tempp = '<div class="sidebar_todo_ ...

  4. 如何在单元测试中测试异步函数,block回调这种

    大概有四种方法: runloop 阻塞主进程等待结果 semphaore 阻塞主进程等待结果 使用XCTestExpectation 阻塞主线程等待(我用这个,xcode自带的,为啥不用) 使用第三方 ...

  5. JavaScript中的异步函数

    JavaScript中的异步函数 ES8 的 async/await 旨在解决利用异步结构组织代码的问题.为此, ECMAScript 对函数进行了扩展,为其增加了两个新关键字: async 和 aw ...

  6. Node.js用ES6原生Promise对异步函数进行封装

    Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...

  7. JS中的异步与回调

    问题的引出:在js中使用异步调用时,有可能会出现在异步的回调函数中设置调用之外的变量值,但在异步调用完成后去使用变量,却发现这些变量值并没有被成功设置的情况.如: google map中的地理编码,地 ...

  8. python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务

    python模块Asynico提供了管理事件.携程.任务和线程的功能已经编写并发代码的同步原语. 组成模块: 事件循,Asyncio 每个进程都有一个事件循环. 协程,子例程概念的泛化,可以暂停任务, ...

  9. 【JS】336- 拆解 JavaScript 中的异步模式

    点击上方"前端自习课"关注,学习起来~ JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS ...

随机推荐

  1. CMU Database Systems - Sorting,Aggregation,Join

    Sorting 排序如果可在内存里面排,用经典的排序算法就ok,比如快排 问题在于,数据表中的的数据是很多的,没法一下都放到内存里面进行排序 所以就需要用到,外排,多路并归排序 看下最简单的,2路并归 ...

  2. [Eclipse]已经写好的代码怎样切换为unix下的换行符?

    问题:使用eclise提交文件到github,每行文件后面都有^M字符 切换换行符的显示格式, 但是这样只能对新文件起作用,修改旧文件:

  3. python获取公网ip的几种方式

    python获取公网ip的几种方式 转 https://blog.csdn.net/conquerwave/article/details/77666226 from urllib2 import u ...

  4. cordova run android 可能遇到的错误解决

    运行: ionic cordova build 等待下载,然后根据提示 输入android或者ios平台,即可 运行cordova run android 报错: 最快捷的解决方法就是使用Androi ...

  5. Dart自定义库、系统库和第三方库

    /* 前面介绍Dart基础知识的时候基本上都是在一个文件里面编写Dart代码的,但实际开发中不可能这么写,模块化很重要,所以这就需要使用到库的概念. 在Dart中,库的使用时通过import关键字引入 ...

  6. Dart 变量、常量和命名规则

    /* Dart 变量: dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推导 dart中定义变量可以通过var关键字可以通过类型来申明变量 如: var str='this is ...

  7. Qt QLabel加载图片

    QLabel加载图片 //在对应的控件中显示图片 void qm_img::DisplayImg(cv::Mat imgParam, QLabel *labelParam) { if (!imgPar ...

  8. Spring Cloud Config 分布式配置管理 5.3

    Spring Cloud Config简介 在传统的单体式应用系统中,我们通常会将配置文件和代码放在一起,但随着系统越来越大,需要实现的功能越来越多时,我们又不得不将系统升级为分布式系统,同时也会将系 ...

  9. matplot画3d图像

    import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np fig = plt ...

  10. jenkins安装插件一直不动

    刷新界面即可,查看已安装的插件即可,这个时候已经安装完了,不用重启,直接使用插件即可