關於for迴圈裡面非同步操作的問題

2022-01-31 09:15:58 字數 2886 閱讀 2500

首先來看乙個比較簡單的問題,我們想實現的就是每隔1s輸出0-4的值,就是這麼簡單,看下錯誤寫法:

function test() , 1000);

}}test();

以上**會如何輸出?輸出如下:

index is : 5

index is : 5

index is : 5

index is : 5

index is : 5

而且該操作幾乎是在同一時間完成,settimeout定時根本就沒有起作用,這是因為:單執行緒的js在操作時,對於這種非同步操作,會先進行一次「儲存」,等到整個for迴圈執行結束後,此時i的值已經變成5,因為settimeout是寫在for迴圈中的,相當於存在5次定時呼叫,這5次呼叫均是在for迴圈結束後進行的,所以自然而然輸出都是5,正確的實現有幾種,一般情況下,我們使用遞迴實現,如下:

// var i = 0;

// var arr = [0, 1, 2, 3, 4];

// function box6() , 1000);

// }

// }

box6();

function box7(param) , 1000)

}}box7(0);

正確實現每隔1s列印輸出如下:

index is : 0

index is : 1

index is : 2

index is : 3

index is : 4

使用遞迴實現的倒計時:

function showtime(count)  else , 1000);

}}showtime(20);

遞迴呼叫很好的解決了settimeout同時執行的情況,如果使用async、await實現,可以如下寫法:

var asyncfunc = function(arr, i) , 1000);

});}var box5 = async function()

console.log(arr);

}box5();

同樣實現每隔1s正確地列印輸出如下:

index is :  0

index is : 1

index is : 2

index is : 3

index is : 4

[ 0, 1, 2, 3, 4 ]

接下來再看個需求:構建乙個函式陣列,該陣列每一項函式的功能是依次輸出0-4,錯誤寫法如下:

function buildlist(list) );

}return result;

}function testlist()

}testlist();

輸出如下:

item3 undefined

item3 undefined

item3 undefined

for迴圈裡面使用匿名函式和直接寫settimeout呼叫比較類似,但是這裡又有點不同,for迴圈執行結束後,匿名函式開始呼叫,發現裡面存在「item」變數,這時依次會向上級查詢,恰好找到迴圈結束時的item變數值為「list[2]」即為3,item為3但是i的值已經變為3,又因為list[3]的值為undefined,所以這裡輸出3遍item3 undefined。不信可以修改下陣列如下,其餘**不變:

function buildlist(list) 

function testlist()

testlist();

這裡絕對輸出的是:

item8 undefined

item8 undefined

item8 undefined

再來看下正確的實現:

function buildlist(list) 

}(i, item));

}return result;

}function testlist()

}testlist();

輸出如下:

item6 6

item7 7

item8 8

這裡主要使用的是即時執行函式,什麼是即時執行函式?可以理解為乙個封閉的**塊,該**塊中的**會在定義時立即執行一遍,各個**塊的作用域彼此獨立,不會汙染外部環境,寫法其實有很多種,上面只是一種,同樣的還有使用void、+、-、!等等,jquery原始碼就是直接使用的這裡的圓括號寫法的這種。

再看幾個測試例子:

function box2() )(i); //這時候這個括號裡面的i和上面arr[i]的值是一樣的都是取自for迴圈裡面的i                            

}return arr;

}console.log(box2()); //[ 0, 1, 2, 3, 4 ]

function box4() 

})(i); //這時候這個括號裡面的i和上面arr[i]的值是一樣的都是取自for迴圈裡面的i

}return arr;

}console.log(box4()); //[ [function], [function], [function], [function], [function] ]

box4這種寫法其實跟上面有一種是一致的,就不多說了,其實主要就是閉包,稍微改變一下**,實現的結果卻截然不同,共勉吧。。。

非同步fifo 關於非同步fifo的快轉慢的問題

最近一位童鞋跟我聊到乙個非同步fifo的問題,還是很有水準的。我貼在這裡給大家看一下 非同步fifo需要將讀寫的pointer作比較產生滿和空訊號,但是假如fifo的兩個時鐘域的clk相差特別大,pointer在做跨時鐘域轉換的時候就會出現問題。什麼問題呢?慢時鐘採快時鐘會漏採資料。舉個栗子 非同步...

小謝第22問 for迴圈中的非同步事件

如果在for迴圈中寫乙個函式,然後等待for迴圈中的函式結束後再進行下一步函式請求,再js中,我們顯然要進行同步處理,可以用async await進行處理,如下方 場景 因為要for 迴圈後才執行this.gettable這個函式,因此用await將api函式變為同步,等待for迴圈執行結束後再執行...

關於迴圈遍歷map容器,erase元素的問題

發現跳過了c,這是為什麼?原因 我們假設迭代器有6個位置0,1,2,3,4,5,對應a,b,c,d,e,f,當刪除b後 內容變成了0,1,2,3,4 對應a,c,d,e,f,迭代器位置為2 2的位置對應了d,跳過了c 正確用法 int main else std cout endl for std ...