初步淺析瀏覽器異步機(jī)制

先說一下JavaScript異步的概念:
首先因?yàn)閖s是單線程的語言旗笔,且沒有異步的特性。

然后js的宿主環(huán)境是在瀏覽器端离例,js的異步操作是瀏覽器來提供的,瀏覽器的js引擎在執(zhí)行js代碼的時(shí)候也只是會(huì)提供一條線程去執(zhí)行悉稠,真摳...并且宫蛆!js(主棧列內(nèi)的js,后文解析什么是主棧列)代碼執(zhí)行會(huì)阻塞渲染線程和瀏覽器事件觸發(fā)線程的猛,后面這兩個(gè)線程是屬于瀏覽器內(nèi)的常駐線程耀盗,當(dāng)然還有其他的比如說http請求線程,那么比如說我們js代碼內(nèi)有一個(gè)是改變某個(gè)DOM元素樣式的代碼卦尊,執(zhí)行了之后只是記錄下這個(gè)渲染事件叛拷,不會(huì)去切換渲染線程進(jìn)行渲染,而是繼續(xù)執(zhí)行剩下的主棧列內(nèi)的代碼岂却,好煩..發(fā)現(xiàn)又要解析主棧列和任務(wù)隊(duì)列的概念..可以去看阮一峰的event loop解析忿薇,就是說,算了上代碼吧:

$.ajax({   
type:'get',   
url:url,  
beforeSend:function() {
      console.log('發(fā)送請求了,別看我在ajax內(nèi),其實(shí)跟它沒什么關(guān)系')         
   },  
success:function(data){      
      console.log('ajax執(zhí)行完畢,我比setTimeout的事件優(yōu)先級(jí)要高')            
   },  
})
setTimeout(function() {   
console.log('定時(shí)器也完了')
},0)
console.log('我在主棧列躏哩,讓我先走')
//觸發(fā)順序
1.發(fā)送請求了,別看我在ajax內(nèi),其實(shí)跟它沒什么關(guān)系
2.我在主棧列署浩,讓我先走
3.jquery-1.9.1.min.js:5 XHR finished loading: GET "http://localhost:2000/123".
4.ajax執(zhí)行完畢
5.定時(shí)器也完了

js引擎在解析js代碼的時(shí)候,遇到settimeout和setInterval或者ajax都會(huì)先告訴它們緩緩扫尺,你們先進(jìn)任務(wù)隊(duì)列里面等等筋栋,我執(zhí)行完剩下在主棧列內(nèi)的代碼先。

然后執(zhí)行完主棧列的代碼之后正驻,js線程完事之后弊攘,并不會(huì)馬上去任務(wù)隊(duì)列內(nèi)找任務(wù)放到主棧列,而是..先查找剛剛是不是有需要渲染引擎要干的是..比如說你要改某個(gè)DOM元素的背景色姑曙,如果有的話襟交,那么就會(huì)切換渲染線程,先把頁面的渲染需要的repaint和reflow做了伤靠,關(guān)于repaint和reflow在這里不做陳述婿着,有興趣google一下吧。

那讓渲染引擎做完了渲染工作醋界,瀏覽器才回去查找任務(wù)隊(duì)列有沒有人掛號(hào)竟宋,采取的是輪詢機(jī)制,跟醫(yī)生看病人差不多形纺,就是說一個(gè)一個(gè)來丘侠,隨便說一句ajax比settimeout和setInterval優(yōu)先級(jí)要高的,比如說執(zhí)行完ajax事件1逐样,就回去看任務(wù)隊(duì)列蜗字?nonono打肝,先看有沒有渲染引擎要做的事,就是說再走一次剛剛主棧列的流程挪捕,沒有渲染的事了粗梭?那就下一位病人吧。

回到主題...為什么我們需要異步级零,因?yàn)閯倓偳拔乃f的js阻塞断医,如果說ajax是同步執(zhí)行的..那么就會(huì)等服務(wù)器響應(yīng)我的請求,拿到數(shù)據(jù)再做其他事情奏纪,那如果服務(wù)器不行請求很久那豈不是很low鉴嗤,那么瀏覽器干了什么就是在走到ajax的時(shí)候,在把它推到任務(wù)隊(duì)列之前序调,起一個(gè)http線程醉锅,去發(fā)送請求,請求完成了发绢,再講ajax事件推到任務(wù)隊(duì)列的末端硬耍,從而實(shí)現(xiàn)異步,在說一句就是根據(jù)上面所說的其實(shí)settimeout和setInterval要比預(yù)期的事件要多一點(diǎn)的边酒,因?yàn)樵陉?duì)列中默垄,不是即刻執(zhí)行,明天再更新甚纲。

好吧口锭,干貨來了,在日常的寫(lu)作(ma)中我們應(yīng)該怎么樣優(yōu)(zuo)雅(si)地利用異步機(jī)制去完成我們想要的異步操作呢:

(一)welcome to callback hell(回調(diào)函數(shù))

function getSomething(fn){
   var num=0;
   settimeout(function(){
       num=1;
       fn(num);
   })
}
function compute(x) {
   alert(x * 2);
}
getSomething(compute);//任性介杆,不喜歡大小寫命名法

如上文所說鹃操,settimeout內(nèi)的js代碼都進(jìn)入了主棧列,那么執(zhí)行順序就是從上至下了春哨,但是在復(fù)雜的需求下這種方法會(huì)產(chǎn)生callback hell荆隘,并且還不容易看出詳細(xì)異步步驟,不簡單的邏輯的話可以用用赴背。

(二)promise

function getSomething() { 
    var r = 0; 
    return new Promise(function(resolve) { 
        setTimeout(function() { 
            r = 2; 
            resolve(r); 
        }, 10); 
    });}
function compute(x) { 
    alert(x * 2);
}
getSomething().then(compute);
//沒有接觸Promise的朋友可以去看看Promise的使用椰拒,因?yàn)橐粫r(shí)半會(huì)又講不完...本文僅提供異步方法

(三)generator

function getSomething() {   
    var r = 0;   
    setTimeout(function() {      
        r = 2;      
        it.next(r);   
    }, 10);
}
function *compute(it) {   
    var x = yield getSomething();   
    alert(x * 2);
}
var it = compute();
it.next();
//我只負(fù)責(zé)提供demo......詳細(xì)可以去看es6的教程

(四)promise + generator

function getSomething() {   
    var r = 0;   
    return new Promise(function(resolve) {      
    setTimeout(function() {         
        r = 2;         
        resolve(r);      
    }, 10);   
 });
}
function *compute() {   
    var x = yield getSomething();   
    alert(x * 2);
}
var it = compute();it.next().value.then(function(value) {   
    it.next(value);
});

(五)async (ES6都玩膩了,ES7還遠(yuǎn)嗎凰荚,異步操作終極大法)

function getSomething() { 
    var r = 0; 
    return new Promise(function(resolve) { 
        setTimeout(function() { 
        r = 2; 
        resolve(r); 
    }, 10); 
});}
async function compute() { 
    var x = await getSomething(); 
    alert(x * 2);
}
compute();

困死本寶寶了..1點(diǎn)了燃观。

好咯,晚安便瑟,world peace.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缆毁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子到涂,更是在濱河造成了極大的恐慌脊框,老刑警劉巖颁督,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浇雹,居然都是意外死亡沉御,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門昭灵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吠裆,“玉大人,你說我怎么就攤上這事虎锚×蛱担” “怎么了衩婚?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵窜护,是天一觀的道長。 經(jīng)常有香客問我非春,道長柱徙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任奇昙,我火速辦了婚禮护侮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘储耐。我一直安慰自己羊初,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布什湘。 她就那樣靜靜地躺著长赞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闽撤。 梳的紋絲不亂的頭發(fā)上得哆,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機(jī)與錄音哟旗,去河邊找鬼贩据。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闸餐,可吹牛的內(nèi)容都是我干的饱亮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舍沙,長吁一口氣:“原來是場噩夢啊……” “哼近尚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起场勤,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戈锻,失蹤者是張志新(化名)和其女友劉穎歼跟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體格遭,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哈街,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拒迅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骚秦。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖璧微,靈堂內(nèi)的尸體忽然破棺而出作箍,到底是詐尸還是另有隱情,我是刑警寧澤前硫,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布胞得,位于F島的核電站,受9級(jí)特大地震影響屹电,放射性物質(zhì)發(fā)生泄漏阶剑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一危号、第九天 我趴在偏房一處隱蔽的房頂上張望牧愁。 院中可真熱鬧,春花似錦外莲、人聲如沸猪半。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磨确。三九已至,卻和暖如春淋昭,著一層夾襖步出監(jiān)牢的瞬間俐填,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工翔忽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留英融,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓歇式,卻偏偏與公主長得像驶悟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子材失,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評論 25 707
  • 剛開始使用JS異步的時(shí)候痕鳍,有這樣的疑問:JS不是單線程的嗎?為什么會(huì)有異步機(jī)制?但是如果沒有異步機(jī)制笼呆,定時(shí)器又是怎...
    盛夏晚清風(fēng)閱讀 1,633評論 0 11
  • 五月熊响,美好的時(shí)光 你的眼睛猶如朝陽 清澈透明而有溫度 你的微笑猶如晨風(fēng) 穿越歲月依然純真美好 你的雙手能撐得起屋頂...
  • 有這樣的幾個(gè)階段。 初高中甚至大學(xué)的時(shí)候我都愛寫那些矯揉造作的東西诗赌,那些把各色形容詞名詞拼命堆砌在一起汗茄,看起來就像...
    陳蹦迪閱讀 344評論 0 3
  • Mybatis 簡介 MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL铭若、存儲(chǔ)過程以及高級(jí)映射洪碳。MyBa...
    sT丶閱讀 552評論 0 0