項目上線了,閑下來就寫寫東西吧。積累了好多東西都沒有做筆記~挑幾個印象深刻的記錄一下吧。
js的同步異步以及單線程問題:
都知道單線程是js的一大特性。但是通常io(ajax獲取服務器數據)、用戶/瀏覽器自執行事件(onclick、onload、onkeyup等等)以及定時器(setTimeout、setInterval)這些異步操作又是怎樣工作的呢。
我們把js的任務分為兩種:同步任務,異步任務:
舉個例子吧: let a=1;
console.log("同步任務");
setTimeout(()=>{console.log("異步任務1");},0);
setTimeout(()=>{console.log("異步任務2");},100);
1、其實js會先將所有的同步任務推入到執行棧中;
2、執行棧中的任務全部執行完畢;(如果error導致阻塞,那么將影響到步驟3)
3、將異步任務(setTimeout)按時間順序推入任務隊列中;
4、執行異步任務;
ps:很明顯setTimeout和setInterval並不是完全精確。https://github.com/woai30231/javascriptThreadStudy(javascript線程及與線程有關的性能優化)
js console.log同步異步?:這個問題是在調試的時候遇到的,我發現有時候console.log並不會給我預期的結果,后來查查資料(參考《你不知道的javascript中卷》第二部分異步和性能 1.1 異步控制台部分)。
並沒有什么規范或一組需求指定console.* 方法族如何工作——它們並不是JavaScript 正式的一部分,而是由宿主環境(請參考本書的“類型和語法”部分)添加到JavaScript 中的。因此,不同的瀏覽器
和JavaScript 環境可以按照自己的意願來實現,有時候這會引起混淆。尤其要提出的是,在某些條件下,某些瀏覽器的console.log(..) 並不會把傳入的內容立即輸出。出現這種情況的主要原因是,在許
多程序(不只是JavaScript)中,I/O 是非常低速的阻塞部分。所以,(從頁面/UI 的角度來說)瀏覽器在后台異步處理控制台I/O 能夠提高性能,這時用戶甚至可能根本意識不到其發生。
什么意思呢?我們還是舉個例子來說: var a={name:"小Q"};
console.log(a);
a.name="snail";
我們通常認為恰好在執行到console.log(..) 語句的時候會看到a 對象的快照,大多數情況下我們看到的是"小Q”,但是,有時候瀏覽器可能會吧控制台I/O延遲到后台,這時候我們看到的可能是"snail",到底什么
時候控制台I/O 會延遲,甚至是否能夠被觀察到,這都是游移不定的。如果在調試的過程中遇到對象在console.log(..) 語句之后被修改,可你卻看到了意料之外的結果,要意識到這可能是這種I/O 的異步化造成的。
如果遇到這種少見的情況,最好的選擇是在JavaScript 調試器中使用斷點,而不要依賴控制台輸出。次優的方案是把對象序列化到一個字符串中,以強制執行一次“快照”,比如通過JSON.stringify(..)。