为什么遇到循环延时操作了。一切源于在小程序开发过程中循环生成多个二维码事件,二维码画图太慢,在读取 canvas 画图地址时,不给一定盾延时是无法读取到图片地址的。再加上小程序不支持多线程。画图需要一定的时间,又处于占用时期。基本情况就是能生成第一个二维码,之后都读取不到地址。
Before
1 2 3 4 5
| for (let id in data) { console.log(id); this.createQr(id, content); }
|
基本输出:
1 2 3 4 5
| 0 1 2 ... { createQr() 输出结果 }
|
可以看出循环很快结束,createQr()的执行结果在循环 log 之后。
for 循环会快速遍历 data 数组,又是单线程,最后 id=0 之后的 createQr()都是失败的。所以希望能都等一会,再循环下一个。
Next
想试试加个延时看看
1 2 3 4 5 6
| for (let id in data) { setTimeout(() => { console.log(id); this.createQr(id, content); }, 1000); }
|
基本输出:
1 2 3 4 5 6
| n n n ... // 等待了 1s { createQr() 输出结果 }
|
可以知道还是循环先执行,1s 之后已经是最后一个 id 了。所以延时不能添加到 for 循环里。
And Next
createQr() 中添加延时试试
1 2 3 4 5 6 7 8 9 10
| for (let id in data) { console.log(id); this.createQr(id, content); }
creatQr: function (id, content) { setTimeout( () => { }, 1000); }
|
基本输出:
1 2 3 4 5 6
| 0 1 2 ... // 等待了 1s { createQr() 输出结果 }
|
是不是感觉又回到了起点?
实际情况是:等于 for 循环同时调用 data.length 个 createQr(); 等待 1s 在执行 createQr()内的内容。由于单线程,又只是执行了一个。
其实我们想的不过就是第 1s: ->createQr() ; 第 2s: ->create() ; 第 3s: ->create() ; …… 所以我需要 梯度延时
Now
1 2 3 4 5 6 7 8 9 10
| for (let id in data) { console.log(id); this.createQr(id, content); }
creatQr: function (id, content) { setTimeout( () => { }, id*1000); }
|
基本输出:
1 2 3 4 5 6 7 8 9 10 11
| 0 1 2 ... // 等待了 1s { createQr() 输出结果 } // 等待了 1s { createQr() 输出结果 } // 等待了 1s { createQr() 输出结果 } ...
|
现在基本上算是解决了画图延时带来的问题。
Demo
1 2 3 4 5
| for (var i = 0; i < 5; i++) { (function(i) { setTimeout(function() { console.log(i); }, 100 * i); })(i); }
|
console 间隔 100ms 循序输出
使用let -块级作用域 就不需要IIFE写法了