1. 程式人生 > >setTimeout、同步、非同步的理解

setTimeout、同步、非同步的理解

js-setTimeout的理解

最近在牛客網上面刷題,遇到了一個場景,就是setTimeout 函式的應用,就是定時的獲取介面重新整理的資料,好了,我們話不多說,直接上程式碼,如下:

console.log("one");
    setTimeout(function (){
        console.log("two");
    },0);
console.log("three");

控制檯輸出結果
在控制檯執行出來的結果是– one three two ,看到這個結果,那你就能想來這個題目不是這麼的簡單了,查閱資料有以下的知識點:
瞭解setTimeout 與 clearTimeout


setTimeout 接受兩個引數,第一個是包含js程式碼的字串和函式,第二個引數是等待多長時間的毫秒數,但經過該事件指定的程式碼不一定執行(下面講解緣由)。clearTimeout 接受一個setTimeout 返回的id 值作為引數傳遞給它,取消程式碼的執行。

//設定超時呼叫
var timeoutId = setTimeout(function (){
    alert("hello World");
    },1000);
//取消掉用的程式碼
clearTimeout(timeoutId);

JavaScript中沒有任何程式碼是立即執行的,但是隻用程序一旦空閒就會立即執行,所以題目中設定的事件不過是經過多少毫秒數被新增到了佇列中,而不是經過多少時間後就被執行。
在這裡,我們需要有一點程序,執行緒的知識來支撐我們理解js中同步,非同步的程式設計思想


眾所周知,javascript是一門單執行緒的語言,即在js引擎中負責解釋和執行js程式碼的執行緒只能有一個,但是,我們知道瀏覽器是多執行緒的。html5中提出了新的web標準,允許javascript 指令碼建立多個執行緒,但子執行緒完全受主執行緒控制,且不得進行Dom操作,因此也並沒有改變單執行緒的本質。
同步非同步的理解
同步:假如一個函式返回時,呼叫者就能夠得到預期結果(拿到了預期的返回值或者看到了預期的效果),這就是同步函式。

alert("hello World");
console.log("hello World");

非同步:呼叫一個函式,返回的值不是預期的結果,需要通過一定的手段才能得到預期的返回值,這就是非同步函式

var timeoutId = setTimeout(function (){
        alert("hello World");
    },1000);

非同步執行的過程:
主執行緒發起一個非同步請求,相應的工作執行緒(比如瀏覽器的其他執行緒)接收請求並告知主執行緒已收到(非同步函式返回);主執行緒可以繼續執行後面的程式碼,同時工作執行緒執行非同步任務;工作執行緒完成工作後,通知主執行緒;主執行緒收到通知後,執行一定的動作(呼叫回撥函式)。(工作執行緒將訊息放到訊息佇列中,主執行緒通過時間迴圈去逐個取資訊,)

發起函式 – 發起非同步過程
回撥函式 – 返回處理結果
事件迴圈的機制
主執行緒只會做一件事,就是從訊息佇列裡面取訊息、執行訊息。當訊息佇列為空時,就會等待訊息佇列變成非空。只有當前的訊息執行結束,才會去取下一個訊息。這種機制就叫做事件迴圈機制Event Loop,取一個訊息並執行的過程叫做一次迴圈。
setTimeout 函式的解決
在瞭解了以上的知識點後,我們就能夠對setTimeout 函式有很好的理解,在執行我們本頁開始的程式碼的時候,先在控制檯輸出 one ,然後主執行緒發起非同步請求,工作執行緒接受請求,將setTimeout 經過設定的時間數推入訊息佇列,最終通過事件迴圈取出訊息進行呼叫,這就是我們剛才開始看到結果的原因了。

好了,以上就是我對setTimeout 以及js同步非同步的瞭解,如果有什麼補充的,歡迎小夥伴們留言指正,謝謝!