for 循环中的setTimeout(function(){})异步问题,为什么改var 为let就可以解决?

发布于 2022-09-02 00:49:06 字数 640 浏览 12 评论 0

1 for (var i=1; i<=9; i++) {
2     setTimeout( function timer(){
3     console.log( i );
4     },1000 );
5 }

上面的代码,由于setTimeout是异步的,那么在真正的1000ms结束前,其实10次循环都已经结束了
为什么改成let这样就可以解决?

1 for (let i=1; i<=9; i++) {
2     setTimeout( function timer(){
3         console.log( i );
4     }, 1000 );
5 }

还有另外一种方法,改成

1 for (var i=1; i<=9; i++) {
2     (function(j){
3         setTimeout( function timer(){
4             console.log( j );
5         }, 1000 );
6     })( i );
7 }

我觉得这种方法也是在timer()之外传入了参数i,跟一开始那个错误的代码并没有什么区别啊,为什么多加一层匿名函数就可以解决异步问题?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿咻 2022-09-09 00:49:06

这两种方法都不是解决异步问题的,而是解决变量作用域的问题的。

因为函数 timer() 属于一个新的域,通过 var 定义的变量是无法传入到这个函数执行域中的,于是有了你展示的两种解决办法,第一种是通过使用 let 来声明块变量,这时候变量就能作用于这个块,所以 timer 就能使用 i 这个变量了。第二种是通过传入参数,间接的把变量传入到 timer 中。

行至春深 2022-09-09 00:49:06

在闭包中,变量是沿着作用域链进行访问的,这样就只能访问变量的最终值。而利用函数参数传值就可以达到预期的要求。多看看 闭包 作用域链的相关知识点就明白了。javascript 高级程序设计一书对这点讲解的特别详细。

随遇而安 2022-09-09 00:49:06

仔细看了一遍~,setTimeout写在for循环里面,相当于执行了9个setTimeout(),用var声明的变量是函数级变量,可以被这9个setTimeout()共享,用let声明的是块作用域,只能被单个setTimeout()引用,而且setTimeout执行在for之后,等于是过一会,同时执行了9个setTimeout函数,不同意见,求回复~

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文