JavaScript之異步編程

最早js語言就是運行在瀏覽器端的語言吐句,目的是為了實現(xiàn)頁面上的動態(tài)交互牺勾。實現(xiàn)頁面交互的核心就是DOM操作,這就決定了它必須使用單線程模型伐债,否則就會出現(xiàn)很復雜的線程同步問題。 假設在js中有多個線程一起工作致开,其中一個線程修改了這個DOM元素峰锁,同時另一個線程又刪除了這個元素,此時瀏覽器就無法明確該以哪個工作線程為準喇喉。所以為了避免線程同步的問題祖今,從一開始,js就設計成了單線程的工作模式拣技。

單線程優(yōu)缺點:
單線程優(yōu)點就是更安全千诬,簡單;缺點就是如果碰到很耗時的任務(比如ajax請求膏斤,文件讀寫)徐绑,會出現(xiàn)假死情況,用戶體驗差莫辨,所以就出現(xiàn)了同步任務和異步任務來解決這個問題傲茄;


同步模式和異步模式

  • 同步模式:代碼按順序一行一行執(zhí)行,是典型的請求-相應模式沮榜,執(zhí)行順序和編寫順序保持一致盘榨;
console.log('global begin')
function bar () {
    console.log('bar task') 
}
function foo () {
    console.log('foo task')
    bar()
}
foo()
console.log('global end')

// global begin
// foo task
// bar task
//global end

// 使用調用棧的邏輯
  • 異步模式:任務可以同時執(zhí)行,不必等待上一個任務結束才繼續(xù)執(zhí)行蟆融;(比如生活中草巡,你可以同時燒水和煮飯一樣)
console.log('global begin')
// 延時器
setTimeout(function timer1 () {
    console.log('timer1 invoke')
}, 1800)
// 延時器中又嵌套了一個延時器
setTimeout(function timer2 () {
    console.log('timer2 invoke')
    setTimeout(function inner () {
        console.log('inner invoke')
    }, 1000)
}, 1000)
console.log('global end')

// global begin
// global end
// timer2 invoke
// timer1 invoke
// inner invoke

//除了調用棧,還用到了消息隊列和事件循環(huán)

js 執(zhí)行異步代碼而不用等待型酥,是因有為有 消息隊列和事件循環(huán)山憨。

  • 消息隊列:消息隊列是一個先進先出的隊列,它里面存放著各種消息弥喉。
  • 事件循環(huán)(EventLoop):事件循環(huán)是指主線程重復從消息隊列中取消息郁竟、執(zhí)行的過程

事件循環(huán)流程:

  1. 宿主環(huán)境(node 服務器或者瀏覽器)為 js 創(chuàng)建線程時,會創(chuàng)建堆(heap)和棧(stack)由境, 堆內存儲 javaScript 對象棚亩,棧內存儲執(zhí)行上下文;
  2. 棧內執(zhí)行上下文的同步任務虏杰,執(zhí)行完即退棧讥蟆;當執(zhí)行異步任務時,該異步任務進入等待狀態(tài)(不入棧),同時通知異步進程嘹屯,執(zhí)行完該異步進程后的回調放到消息隊列中
  3. 當棧內同步任務執(zhí)行結束后攻询,依次執(zhí)行消息隊列中的任務
    注:js是單線程的,瀏覽器不是單線程的州弟,有一些API是有單獨的線程去做的
    image.png

宏任務和微任務

  • 宏任務(macrotask):每次執(zhí)行棧執(zhí)行的代碼就是宏任務(包括每次從消息隊列中獲取一個事件回調并放到執(zhí)行棧中執(zhí)行)
  • 微任務(microtask):當前宏任務執(zhí)行結束后立即執(zhí)行的任務(當前宏任務之后钧栖,下一個宏任務之前);
    所以它的響應速度相比 setTimeout 會更快婆翔,因為無需等待渲染拯杠,也就是說:在某一個宏任務執(zhí)行完后,就會將它執(zhí)行期間產(chǎn)生的所有微任務執(zhí)行完畢啃奴;

舉個例子:
我去銀行排隊辦理業(yè)務潭陪,原本我只想辦理取款業(yè)務(取款業(yè)務當成是宏任務),辦理完取款業(yè)務后,立即我又想辦一個開卡業(yè)務(開卡業(yè)務當成一個微任務);
這個時候依溯,我不會重新去排隊老厌,而是在還沒離開辦理窗口時,立馬讓柜臺人員幫我再次辦理這個業(yè)務黎炉;
如果我還有其他業(yè)務要辦理(更多微任務),都是可以繼續(xù)辦理枝秤,只要我不離開窗口(后面排隊用戶也不應該有任何怨言,因為我有排隊并且沒有離開柜臺)慷嗜。

宏任務包含:

script(整體代碼)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 環(huán)境)

微任務包含:

Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 環(huán)境)

回調函數(shù)(異步編程的根基)

概念:由調用者定義淀弹,交給執(zhí)行者執(zhí)行的函數(shù)
缺點:如果異步函數(shù)嵌套很深,就會不可避免的產(chǎn)生回調地獄

// callback就是回調函數(shù)
function foo(callback) {
    setTimeout(function(){
        callback()
    }, 3000)
}

foo(function() {
    console.log('這就是一個回調函數(shù)')
})

Promise —— 一種更優(yōu)的異步編程統(tǒng)一方案

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末庆械,一起剝皮案震驚了整個濱河市薇溃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缭乘,老刑警劉巖沐序,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異忿峻,居然都是意外死亡薄啥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門逛尚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垄惧,“玉大人,你說我怎么就攤上這事绰寞〉窖罚” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵滤钱,是天一觀的道長觉壶。 經(jīng)常有香客問我,道長件缸,這世上最難降的妖魔是什么铜靶? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮他炊,結果婚禮上争剿,老公的妹妹穿的比我還像新娘。我一直安慰自己痊末,他們只是感情好蚕苇,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凿叠,像睡著了一般涩笤。 火紅的嫁衣襯著肌膚如雪嚼吞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天蹬碧,我揣著相機與錄音舱禽,去河邊找鬼。 笑死锰茉,一個胖子當著我的面吹牛呢蔫,可吹牛的內容都是我干的切心。 我是一名探鬼主播飒筑,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绽昏!你這毒婦竟也來了协屡?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤全谤,失蹤者是張志新(化名)和其女友劉穎肤晓,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體认然,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡补憾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了卷员。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盈匾。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毕骡,靈堂內的尸體忽然破棺而出削饵,到底是詐尸還是另有隱情,我是刑警寧澤未巫,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布窿撬,位于F島的核電站,受9級特大地震影響叙凡,放射性物質發(fā)生泄漏劈伴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一握爷、第九天 我趴在偏房一處隱蔽的房頂上張望跛璧。 院中可真熱鬧,春花似錦饼拍、人聲如沸赡模。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漓柑。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辆布,已是汗流浹背瞬矩。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锋玲,地道東北人景用。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像惭蹂,于是被迫代替她去往敵國和親伞插。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容