深入理解JS中的--同步和非同步
阿新 • • 發佈:2019-01-23
- JS中的兩種程式設計思想:同步、非同步
- JS是單執行緒的 --> JS就是一個傻子,腦子一根筋,做著當前的這件事情,沒有完成之前,絕對不會做下一件事情
- 同步就是 --> 上一件事情沒有完成,繼續處理上一件事情,只有上一件事情完成了,才會做下一件事情 --> JS中大部分都是同步程式設計
<script type="text/javascript"> // JS中的兩種程式設計思想:同步、非同步 //JS是單執行緒的 --> JS就是一個傻子,腦子一根筋,做著當前的這件事情,沒有完成之前,絕對不會做下一件事情 // 同步就是 --> 上一件事情沒有完成,繼續處理上一件事情,只有上一件事情完成了,才會做下一件事情 // --> JS中大部分都是同步程式設計 // for (var i = 0;i < 10000;i++) { // if (i === 9999) { // console.log("迴圈結束了"); // --> (1) // } // } // console.log("ok"); // --> (2) // --> for迴圈就是同步程式設計,只有迴圈結束後,才會繼續執行下面的程式碼 // while (1) { // // } // console.log("ok"); // --> 永遠不會執行,因為上面的迴圈是死迴圈,迴圈永遠不會結束
- 2、非同步 --> 規劃要做一件事情,但是不是當前立馬去執行這件事情,需要等一定的時間,這樣的話,我們不會等著他執行,而是繼續執行下面的操作
- –> “只有當下面的事情都處理完成了,才會返回頭處理之前的事情;如果下面的事情並沒有處理完成,不管之前的事情有沒有到時見,都踏踏實實的給我等著”
- –> 在JS中,非同步程式設計只有四種情況:
- –> 定時器都是非同步程式設計的
- –> 所有的事件繫結都是非同步程式設計的
- –> Ajax讀取資料都是非同步程式設計的,我們一般設定為非同步程式設計
- –> 回撥函式都是非同步程式設計的
// 2、非同步 --> 規劃要做一件事情,但是不是當前立馬去執行這件事情,需要等一定的時間,這樣的話,我們不會等著他執行,而是繼續執行下面的操作 // --> “只有當下面的事情都處理完成了,才會返回頭處理之前的事情;如果下面的事情並沒有處理完成,不管之前的事情有沒有到時見,都踏踏實實的給我等著” // --> 在JS中,非同步程式設計只有四種情況: // --> 定時器都是非同步程式設計的 // --> 所有的事件繫結都是非同步程式設計的 // --> Ajax讀取資料都是非同步程式設計的,我們一般設定為非同步程式設計 // --> 回撥函式都是非同步程式設計的 // var n = 0; // window.setTimeout(function () { // n++; // console.log(n); // --> 1 (2) // },1000); // console.log(n); // --> 0 (1) // // --> 先輸出48行,0 --> 再輸出46行,1 //每一個瀏覽器對於定時器的等待時間都有一個最小的值,谷歌5-6毫秒;IE 10-13毫秒 //如果設定的等待時間小於這個值,不起作用,還是需要等待最小時間才執行; --> 尤其是寫0也不是立即執行 // var n = 0; // window.setTimeout(function () { // n++; // console.log(n); // --> 1 (2) // },0); // --> 0不是立即執行 // console.log(n); // --> 0 (1) // --> 先輸出60行,0 --> 再輸出57行,1 //--> 我們定時器設定的等待時間不一定就是最後的執行時間,如果定時期之後還有其他的事情正在處理中,不管定時器的時間有沒有到,都是不會執行定時器的 // var n = 0; // window.setTimeout(function () { // n++; // console.log(n); // --> 不執行的 // },0); // console.log(n); // --> 0 (1) // while (1) { // --> 死迴圈 // n++; // } // console.lgo(n); // --> 不執行的 //只能執行1次,因為死迴圈這件事情一直執行完成不了 // 任務佇列池 // var n = 0; // window.setTimeout(function () { // n += 2; // console.log(n); // --> 7 (4) // },20); // window.setTimeout(function () { // n += 5; // console.log(n); // --> 5 (3) // },5); // console.log(n); // --> 0 (1) // for (var i = 0;i < 1000000;i++) { // // } // console.log(n); // --> 0 (2) // 0 86、 0 90、 5 7 // for (var i = 0;i < oLis.length;i++) { oLis[i].onclick = function () { tabChange(i); }; } </script>
JavaScript為什麼是單執行緒?eventloop
-
JavaScript的單執行緒,與它的用途有關。作為瀏覽器指令碼語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單執行緒,否則會帶來很複雜的同步問題。
-
非同步執行:
(1)所有同步任務都在主執行緒上執行,形成一個執行棧(execution context stack)。
(2)主執行緒之外,還存在一個"任務佇列"(task queue)。只要非同步任務有了執行結果,就在"任務佇列"之中放置一個事件。
(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。
(4 )主執行緒不斷重複上面的第三步。
主執行緒從”任務佇列”中讀取事件,這個過程是迴圈不斷的,所以整個的這種執行機制又稱為Event Loop(事件迴圈)。