這篇文章主要介紹了深入理解JavaScript編程中的同步與異步機制,不僅僅是AJAX已經(jīng)深入到了各個角落,Node.js的火爆也讓JS的異步編程格外引人注目,需要的朋友可以參考下
JavaScript的優(yōu)勢之一是其如何處理異步代碼。異步代碼會被放入一個事件隊列,等到所有其他代碼執(zhí)行后才進行,而不會阻塞線程。然而,對于初學者來說,書寫異步代碼可能會比較困難。而在這篇文章里,我將會消除你可能會有的任何困惑。
理解異步代碼
JavaScript最基礎(chǔ)的異步函數(shù)是setTimeout和setInterval。setTimeout會在一定時間后執(zhí)行給定的函數(shù)。它接受一個回調(diào)函數(shù)作為第一參數(shù)和一個毫秒時間作為第二參數(shù)。以下是用法舉例:
?
1 2 3 4 5 6 7 8 9 10 11 console.log( "a" ); setTimeout(function() { console.log( "c" ) }, 500 ); setTimeout(function() { console.log( "d" ) }, 500 ); setTimeout(function() { console.log( "e" ) }, 500 ); console.log( "b" );正如預期,控制臺先輸出“a”、“b”,大約500毫秒后,再看到“c”、“d”、“e”。我用“大約”是因為setTimeout事實上是不可預知的。實際上,甚至 HTML5規(guī)范都提到了這個問題:
“這個API不能保證計時會如期準確地運行。由于CPU負載、其他任務(wù)等所導致的延遲是可以預料到的。”
有趣的是,直到在同一程序段中所有其余的代碼執(zhí)行結(jié)束后,超時才會發(fā)生。所以如果設(shè)置了超時,同時執(zhí)行了需長時間運行的函數(shù),那么在該函數(shù)執(zhí)行完成之前,超時甚至都不會啟動。實際上,異步函數(shù),如setTimeout和setInterval,被壓入了稱之為Event Loop的隊列。
Event Loop是一個回調(diào)函數(shù)隊列。當異步函數(shù)執(zhí)行時,回調(diào)函數(shù)會被壓入這個隊列。JavaScript引擎直到異步函數(shù)執(zhí)行完成后,才會開始處理事件循環(huán)。這意味著JavaScript代碼不是多線程的,即使表現(xiàn)的行為相似。事件循環(huán)是一個先進先出(FIFO)隊列,這說明回調(diào)是按照它們被加入隊列的順序執(zhí)行的。JavaScript被 node選做為開發(fā)語言,就是因為寫這樣的代碼多么簡單啊。
Ajax
異步Javascript與XML(AJAX)永久性的改變了Javascript語言的狀況。突然間,瀏覽器不再需要重新加載即可更新web頁面。 在不同的瀏覽器中實現(xiàn)Ajax的代碼可能漫長并且乏味;但是,幸虧有jQuery(還有其他庫)的幫助,我們能夠以很容易并且優(yōu)雅的方式實現(xiàn)客戶端-服務(wù)器端通訊。
我們可以使用jQuery跨瀏覽器接口$.ajax很容易地檢索數(shù)據(jù),然而卻不能呈現(xiàn)幕后發(fā)生了什么。比如:
?
1 2 3 4 5 6 7 8 9 10 var data; $.ajax({ url: "some/url/1", success: function( data ) { // But, this will! console.log( data ); } }) // Oops, this won't work... console.log( data );新聞熱點
疑難解答
圖片精選