js的for循环中出现异步函数,回调引用的循环值总是最后一步的值?
这几天跟着视频学习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循环中出现异步函数,回调引用的循环值总是最后一步的值?的更多相关文章
- js的for循环中出现异步函数,回调引用的循环值始终是最后的值
一.问题 今天工作中解决bug发现是由“for循环的异步函数,回调引用的循环值始终是最后的值”的现象导致的,如: for (var i = 0; i < files.length; i++) { ...
- 简单的node爬虫练手,循环中的异步转同步
简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...
- JS循环中使用bind函数的参数传递问题
JS循环中使用bind函数的参数传递问题,问题代码如下: for (var sc in result) { var tempp = '<div class="sidebar_todo_ ...
- 如何在单元测试中测试异步函数,block回调这种
大概有四种方法: runloop 阻塞主进程等待结果 semphaore 阻塞主进程等待结果 使用XCTestExpectation 阻塞主线程等待(我用这个,xcode自带的,为啥不用) 使用第三方 ...
- JavaScript中的异步函数
JavaScript中的异步函数 ES8 的 async/await 旨在解决利用异步结构组织代码的问题.为此, ECMAScript 对函数进行了扩展,为其增加了两个新关键字: async 和 aw ...
- Node.js用ES6原生Promise对异步函数进行封装
Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...
- JS中的异步与回调
问题的引出:在js中使用异步调用时,有可能会出现在异步的回调函数中设置调用之外的变量值,但在异步调用完成后去使用变量,却发现这些变量值并没有被成功设置的情况.如: google map中的地理编码,地 ...
- python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务
python模块Asynico提供了管理事件.携程.任务和线程的功能已经编写并发代码的同步原语. 组成模块: 事件循,Asyncio 每个进程都有一个事件循环. 协程,子例程概念的泛化,可以暂停任务, ...
- 【JS】336- 拆解 JavaScript 中的异步模式
点击上方"前端自习课"关注,学习起来~ JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS ...
随机推荐
- Unexpected token o in JSON at position 1 报错原因
写在前面的话这个问题在之前做项目时碰到过一次,当时按照网上的做法,去掉JSON.parse()这一层转换后就没有这个报错了,数据也能正常使用,就没多想,也没深究是什么原因. 可是这次又碰到了,所以这次 ...
- taocrypt
taocrypt MySQL Bugs: #25189: mysqld: coding.cpp:243: void TaoCrypt::Base64Decoder::Decode(): Asserti ...
- Alibaba Java Diagnostic Tool Arthas/Alibaba Java诊断利器Arthas
Arthas 用户文档 — Arthas 3.1.0 文档https://alibaba.github.io/arthas/ alibaba/arthas: Alibaba Java Diagnost ...
- Python之Pandas绘图,设置显示中文问题
# -*- coding: utf-8 -*- # author:baoshan import pandas as pd import matplotlib.pyplot as plt plt.rcP ...
- Java学习,从入门到放弃(一)SpringMVC+Maven+Mybits 多种数据库配置(mysql+sqlserver)AOP方式
多数据库配置需求有两种,一种是因为项目太大,访问量太高,不得不分布多个数据库减轻访问压力,比较多的应用就是读写分离:另一种就是原本不同的两个数据库业务现在要整合到一起,甚至连数据库都不一样,一个mys ...
- ovs 数据包的处理过程
Openvswitch的内核模块openvswitch.ko会在网卡上注册一个函数netdev_frame_hook,每当有网络包到达网卡的时候,这个函数就会被调用. static struct sk ...
- Docker快速安装
目前装Docker得最简单方式就是脚本安装了,方法如下: curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh 安装后 ...
- 【深度学习与神经网络】深度学习的下一个热点——GANs将改变世界
本文作者 Nikolai Yakovenko 毕业于哥伦比亚大学,目前是 Google 的工程师,致力于构建人工智能系统,专注于语言处理.文本分类.解析与生成. 生成式对抗网络-简称GANs-将成为深 ...
- 钩子(hook)
钩子(hook)编程 钩子(hook)编程 一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows ...
- C#调试C++DLL库
C#调试C++DLL库 https://blog.csdn.net/gggg_ggg/article/details/51086089 对于托管代码调用非托管DLL文件,已经是非常普遍的事情,下面写一 ...