1. 程式人生 > >javaScript中的同步,異步與回調函數

javaScript中的同步,異步與回調函數

為什麽 .cn cnblogs ffffff 就會 成了 答案 func 技術

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(‘i: ‘,i);
    }, 1000);
}
 
console.log(i);

輸出結果:

//輸出
5
i:  5
i:  5
i:  5
i:  5
i:  5

記住我們的口訣,同步=>異步=>回調

1、for循環和循環體外部的console是同步的,所以先執行for循環,再執行外部的console.log。(同步優先) 2、for循環裏面有一個setTimeout回調,他是墊底的存在,只能最後執行。(回調墊底) 那麽,為什麽我們最先輸出的是5呢? 非常好理解,for循環先執行,但是不會給setTimeout傳參(回調墊底),
等for循環執行完,就會給setTimeout傳參,而外部的console打印出5是因為for循環執行完成了。 這裏涉及到JavaScript執行棧和消息隊列的概念,概念的詳細解釋可以看阮老師的 JavaScript 運行機制詳解:再談Event Loop – 阮一峰的網絡日誌,或者看 並發模型與Event Loop。 技術分享

javaScript單線程如何處理回調呢? javaScript同步的代碼是在堆棧中順序執行的。而setTimeout回調會先放到消息隊列,for循環每執行一次,就會 放一個setTimeout到消息隊列中,排隊等候,當同步代碼執行完了,再去調用消息隊列中的回調方法。 在這個經典例子中,也就是說,先執行for循環,按順序放了5個setTimeout回調到消息隊列,然後for循環結束,下面還有一個同步的console,執行完console之後,堆棧中已經沒有同步的代碼了,就去消息隊列找,發現找到了5個setTimeout,註意setTimeout是有順序的。 那麽,setTimeout既然在最後才執行,那麽他輸出的i又是什麽呢?答案就是5。。有人說不是廢話嗎? 現在告訴大家為什麽setTimeout全都是5,JavaScript在把setTimeout放到消息隊列的過程中,循環的i是不會及時保存進去的,相當於你寫了一個異步的方法,但是ajax的結果還沒返回,只能等到返回之後才能傳參到異步函數中。 在這裏也是一樣,for循環結束之後,因為i是用var定義的,所以var是全局變量(這裏沒有函數,如果有就是函數內部的變量),這個時候的i是5,從外部的console輸出結果就可以知道。那麽當執行setTimeout的時候,由於全局變量的i已經是5了,所以傳入setTimeout中的每個參數都是5。

javaScript中的同步,異步與回調函數