异步这东西很令人讨厌啊,尤其是对我一个Java和C#的程序员来说,经常直来直往的冲进坑里。
各种各样的异步回调这里就不枚举了。自定义一般使用promise实现,这里举例直接用setTimeout。
比如下面段代码,会输出什么呢:
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
不好意思,是十个10。
当然这个举例不恰当,你想输出1~10,把setTimeout去掉就好了。。。
实际上很多时候你想去掉setTimeout,却发现在Web这个大环境下根本去不掉。比如你的网页上要同时访问多个http的接口,需要写进度条;
又或者你要load多个文件,确保load是按你期望的顺序保存到数据内。。。
一般情况下,对我们这种小白最好理解的办法是像下面这样:
let和var的巨大差别在这。let包含了ES6块级作用域
function test() {
for (var i = 0; i < 10; i++) {
let kk = i;
setTimeout(() => {
console.log(kk);
}, 1000)
}
}
传统的办法是构造一个新函数。通过函数参数来传递。
function test() {
for (var i = 0; i < 10; i++) {
function fun(kk) {
setTimeout(() => {
console.log(kk);
}, 1000)
};
fun(i);
}
}
这种情况有什么作用呢。以我比较擅长的threejs为例,比如你的文件拆成了N个json文件,这些json的load是异步的,threejs根本不允许你改成同步,
那如何通过异步的执行,异步其实都是无序的,那如何得到你要的有序的结果?
function test() {
var dataAry = [];
files.foreach(f => {
let tmpindex = dataAry.length;
dataAry.push(-1);
ThreejsJsonLoader.Load(f).then(data =>{
dataAry[tmpindex] = data;
});
});
}
}
在循环内先把dataAry填成-1,重要的是拿到此时f对应的索引位置。在load完成后,利用索引位置对dataAry数组直接赋值。
这样就无视了因为json的大小差异而导致load时间差,如果用push,是解决不了问题的。顺序一定是乱的。