微信小程序、js循环同步请求采坑指南

先给个示例:
for(var i=0;i<3;i++){

  setTimeout(function(){
      console.log(i);
   }, (i+1)*1000); 


}

       一般,我们会认为,这段代码会log出来0,1,2.而实际上,这段代码log出来的结果是 3,3,3。具体原因就是因为for循环的阻塞机制。在上面的代码中,setTimeout这个定时器需要等待for循环 执行完成,而for循环执行完成了之后,i已经为3了,此时才开始执行setTimeout,因此console.log(i)会是3。至于为什么i会是3,当i为2的时候,满足循环条件,执行代码块,然后i++,此时i为3,不满足循环条件,不执行代码块,循环停止。

那什么是阻塞机制呢?

阻塞机制解释

  JavaScript是单线程执行的,无法同时执行多段代码。当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个队列。一旦当前任务执行完毕,再从队列中取出下一个任务,这也常被称为 “阻塞式执行”。所以一次鼠标点击,或是计时器到达时间点,或是Ajax请求完成触发了回调函数,这些事件处理程序或回调函数都不会立即运行,而是立即排队,一旦线程有空闲就执行。
  关键说明:假如当前 JavaScript线程正在执行一段很耗时的代码,此时发生了一次鼠标点击,那么事件处理程序就被阻塞,用户也无法立即看到反馈,事件处理程序会被放入任务队列,直到前面的代码结束以后才会开始执行。如果代码中设定了一个 setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以 setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。

  js阻塞机制,跟Js引擎的单线程处理方式有关,每个window一个JS线程。所谓单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。

阻塞机制解决办法

  其实,阻塞作为js引擎的处理方式,我们最好不要想着解决“阻塞”,而是让我们想执行的代码,插入到“主线程”中。这么说比较不易理解,还是以上面的代码为例,直接上代码好了

for(var i=0;i<3;i++){

  (function(i){

      setTimeout(function(){
        console.log(i);
          }, (i+1)*1000);

      })(i)

 }

       在上面的代码中,我们加了一个立即执行的匿名函数,并且将for循环的i作为实参传入进去。这样,setTimeout就会被立即执行,而不会等待(这里不太了解细节,就不多说了,大概猜测为新开了一个临时的线程,立即执行匿名函数,然后再立即切换回来)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
微信小程序中,你可以使用for循环来遍历数据。有三种常用的方法来实现这个目的。 第一种方法是使用for-in循环。你可以使用for-in循环来遍历一个数组或一个对象的属性。在这种方法中,你可以使用索引来访问数组中的元素。例如,在你的示例中,你可以使用以下代码来遍历users数组: ``` let datas = this.data.users; for (var index in datas) { console.log(index + ' 姓名:' + datas[index].name + ' 年龄:' + datas[index].age);} ``` 第二种方法是使用普通的for循环,并利用数组的length属性来确定循环的次数。在这种方法中,你可以使用索引来访问数组中的元素。例如,在你的示例中,你可以使用以下代码来遍历users数组: ``` let datas = this.data.users; for (var i = 0; i < datas.length; i++) { console.log(i + ' 姓名:' + datas[i].name + ' 年龄:' + datas[i].age); } ``` 第三种方法是使用forEach循环。这个方法是ES6引入的一种遍历数组的方式。在forEach循环中,你可以直接访问数组中的元素,而不需要使用索引。例如,在你的示例中,你可以使用以下代码来遍历users数组: ``` let datas = this.data.users; datas.forEach(function (item, index) { console.log(index + ' 姓名:' + item.name + ' 年龄:' + item.age); }); ``` 在微信小程序的wxml页面中执行循环取值,你可以使用{{}}语法来访问数组的元素。例如,在你的示例中,你可以使用以下代码来展示users数组中的姓名和年龄: ``` <view wx:for="{{users}}"> <text>姓名:{{item.name}} 年龄:{{item.age}}</text> </view> ``` 希望这些方法能帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大麦147

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值