Javascript中的異步

版權聲明: 本文由 一隻博客 發表於 bloghome博客javascript

文章連接: https://www.bloghome.com.cn/user/cnn237111html

在C#,Java中,異步方法,一般是伴隨多線程,併發等術語一塊兒出現的,好比C#中的async方法,是運行在一個線程池線程上,而且在異步方法運行完成後,有一個回調函數通知主線程。html5

那麼因爲Javascript是單線程的,它的異步又是怎麼解釋的?java

首先對異步方法給一個定義,什麼樣的方法算是異步方法。我認爲異步方法最主要有2點,一個是不阻塞當前代碼的執行,另外一個是有回調方法。即異步方法運行完能夠通知主線程。web

事實上,當提及Javascript的異步時,不要忽略了,Javascript中其實有2種異步,一種是基於瀏覽器的的異步IO,好比ajax的本質。另外一種是基於計時方法setTimeout和setInterval的異步。ajax

對於異步IO,好比ajax,寫代碼的時候都是順序執行的,可是在真正處理請求的時候,有一個單獨的瀏覽器線程來處理,而且在處理完成後會觸發回調。這種狀況下,參與異步過程的其實有2個線程主體,一個是javascript的主線程,另外一個是瀏覽器線程。編程

熟悉Javascript的人都知道,Javascript內部有一個事件隊列,全部的處理方法都在這個隊列中,Javascript主線程就是輪詢這個隊列處理,這個好處是使得CPU永遠是忙碌狀態。這個機制和Windows中的消息泵是同樣的,都是靠消息(事件)驅動。對於這個消息隊列的描述,能夠參考http://www.iamued.com/qianduan/1645.html這個文章。瀏覽器

在Javascript中,經過setTimeout函數也能夠實現「不阻塞」和「有回調」。好比,下面的代碼:多線程

function f1(callback){
setTimeout(function () {
// f1的任務代碼
callback();
}, 1000);
}
f1(f2);

經過這種寫法,javascript在調用f1方法的時候,將真正的邏輯放到1秒後,而且在運行完正真的邏輯後,執行了f2方法。仔細的分析一下,其實這種所謂的不阻塞其實只是將阻塞延遲了。單線程環境下,並無法真正的異步。事實上,setTimeout方法對於時間的精度很是差,並不能真的保證是在1秒後執行,若是事件隊列中有一個長時間的方法在運行,那麼就阻塞了真正的f1方法內容的運行,直到長時間的方法容許完畢。等到輪到f1的真正邏輯開始運行的時候,其餘的代碼一樣的要等到它運行完畢才能運行。併發

好比下面的代碼:

setTimeout(function(){alert('do');},0);
var i=0;
while(i<100000){
console.log(i);
i++;
}

並不會立刻運行alert,而是會等到while運行完畢才alert。根據《Javascript異步編程》這本書中提到,setTimeout和setInterval的延時最小間隔是4ms,Quora上也有總結過http://www.quora.com/How-accurate-are-JavaScript-timers

在Javascript中實現異步的另外一個方法是Web Worker,web worker 是運行在後臺的 JavaScript,獨立於其餘腳本,不會影響頁面的性能。Web Workers依賴於瀏覽器,目前支持的lSafari, Chrome, Opera, Internet Explorer (version 10) 和Mozilla Firefox.一旦使用Web Workers就等於使用了多線程技術。Web Workers的更多細節,能夠參考網上的文檔http://www.w3school.com.cn/html5/html_5_webworkers.asp

http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html

相關文章
相關標籤/搜索