Js語言的執(zhí)行環(huán)境是“單線程”就是指一次只能完成一個任務(wù),如果有多個任務(wù),就必須排隊,前面一個任務(wù)完成,再執(zhí)行后面一個任務(wù),以此類推。
單線程的好處是實現(xiàn)起來比較簡單,執(zhí)行環(huán)境相對單純,壞處是只要有一個任務(wù)耗時很長,后面的任務(wù)都必須排隊等著,會拖延整個程序的執(zhí)行。
js分同步模式和異步模式,異步模式,么個任務(wù)有一個或多個回調(diào)函數(shù),前一個任務(wù)結(jié)束后,不是執(zhí)行后一個任務(wù),而是執(zhí)行回調(diào)函數(shù),后一個任務(wù)則是不等前一個任務(wù)結(jié)束就執(zhí)行,所以程序的執(zhí)行順序和任務(wù)的排列順序使不一致的、異步的。
處理異步有幾種常見的方式
- 回調(diào)模式
function f1(callback){
setTimeout(function(){
//f1的任務(wù)代碼
callback()
},1000)
}
//執(zhí)行代碼就變成:f1(f2)
- 回調(diào)函數(shù)的有點是簡單,容易理解和部署,缺點是不利于代碼的閱讀和維護(hù),各個部分之間高度耦合,流程會很混亂,而且每個任務(wù)只能指定一個回調(diào)函數(shù)。
- 事件監(jiān)聽:采用事件驅(qū)動模式。任務(wù)的執(zhí)行不取決于代碼的順序,而取決于某個事件是否要發(fā)生。
f1.on('done',f2)
//當(dāng)f1發(fā)生done事件,就執(zhí)行f2,然后對f1進(jìn)行改寫
functjion f1(){
setTimeout(function(){
//f1的任務(wù)代碼
f1.trigger('done')
},1000)
}
//這種方法的優(yōu)點是,可以綁定多個事件,每個事件可以指定多個回調(diào)函數(shù),而且可以“去耦合”,有利于實現(xiàn)模塊化。缺點是整個程序都編程事件驅(qū)動型,運行流程會變得很不清晰。
- 發(fā)布訂閱:假定存在一個“信號中心”,某個任務(wù)執(zhí)行完成,就向信號中心“發(fā)布”一個信號,其他任務(wù)可以向信號中心“訂閱”這個信號,從而指導(dǎo)什么時候自己可以開始執(zhí)行。這就叫做發(fā)布訂閱模式
//首先f2向信號中心jQuery
訂閱done信號
jQuery.subscribe("done",f2)
//然后進(jìn)行如下改寫
function f1(){
setTimeout(function(){
//f1的任務(wù)代碼
jQuery.publish("done")
},1000)
}
//jQuery.publish('done')的意思是,f1執(zhí)行完成后,向信號中心jQuery發(fā)布done信號,從而引發(fā)f2的執(zhí)行。
此外,f2完成執(zhí)行后,也可以取消發(fā)布訂閱
jQuery.unsubscribe("done",f2)
//這種方法的性質(zhì)與“事件監(jiān)聽”類似,但是明顯優(yōu)于后者。因為可以通過查看消息中心,了解存在多少信號,每個信號有多少訂閱者,從而監(jiān)控程序的執(zhí)行
promise 是什么
Promise 對象是 JavaScript 的異步操作解決方案,為異步操作提供統(tǒng)一接口。它起到代理作用(proxy),充當(dāng)異步操作與回調(diào)函數(shù)之間的中介,使得異步操作具備同步操作的接口。Promise 可以讓異步操作寫起來,就像在寫同步操作的流程,而不必一層層地嵌套回調(diào)函數(shù)。
Promise 并不能消滅回調(diào)地獄,但是它可以使回調(diào)變得可控