異步這東西很令人討厭啊,尤其是對我一個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,是解決不了問題的。順序一定是亂的。