JS高階 分析JS中的非同步操作

2022-05-01 19:57:09 字數 3021 閱讀 3728

js因為是單執行緒的,所以在執行事務的時候,往往會因為某個事務的延遲,而導致伺服器假死,這時候非同步程式設計就顯的格外重要,但是非同步程式設計一般理解為**函式callback,典型的就是node,**函式的層層巢狀又導致程式過於冗餘,因為閉包的存在,導致了記憶體的洩露或者誤改上一層**函式的引數,於是又有乙個疑問,能不能用同步的方式去寫非同步,es6的promise就是以同步流程的方式寫出非同步操做,但是piomise原生操作寫起來比較長,能不能簡介操作promise,es7就又出現async/await的概念,與async/await同等語法糖作用的有依賴co庫的generator函式,generator函式也是用來解決非同步操作,不過得依賴co庫,co 函式庫是著名程式設計師 tj holowaychuk 於2023年6月發布的乙個小工具,用於generator函式的自動執行。

好了,那就羅列出js的非同步操作

1、**函式

ajax典型的非同步操作,利用xmlhttprequest,**函式獲取伺服器的資料傳給前台  

之前也分析過ajax(飛機票)

**函式的含義就是耗時任務f1中執行f2,f1不會堵塞住,而是先執行f2,再延遲執行f1

2、事件監聽

addeventlistener

當監聽事件發生時,先執行**函式,再對監聽事件進行改寫

3、觀察者模式,也叫訂閱發布模式

多個觀察者可以訂閱同乙個主題,主題物件改變時,主題物件就會通知這個觀察者

其中步驟包括,訂閱、發布、退訂;先訂閱(subscribe)乙個主題物件,根據主題物件發布(publish)內容,期間也退訂(unsubscribe)主題物件,一旦退訂就無法再次發布

可以把訂閱乙個主題物件理解成監聽乙個事件

觀察者模式的乙個特點就是一旦主題事件一改變,就會通知整個觀察者;觀察者模式還可以計算出訂閱事件的個數

4、promise

上面也提到了,promise是非同步程式設計的解決方案,是一種容器,儲存著非同步操作的結果,可以把非同步函式以同步函式的形式寫出來

promise第乙個特點:物件狀態不受外界影響,有三個狀態pending(),fulfilled(),rejected(),只有非同步操作才會更改這個狀態,其他操作無法改變這個狀態

promise第二個特點:一旦狀態改變,pending->fulfilled或pending->rejected,狀態就會凝固住,稱為resolve,通過promise的**函式可以立即得到這個結果,與事件監聽不同,一旦事件錯誤,就無法再次監聽

promise第三個特點:避免了**函式的層層巢狀,實際上寫promise時,雖然沒有回到函式的層層巢狀,但是又有then的巢狀,這個又有新的解決方法

promise第乙個缺點:一旦promise建立,就會立即執行,無法中途停止

舉個例子,假如去**買東西,去看上乙個東西,想要買,已經點選確定購買了,但是你又cancle了,突然你發現工資發了,你又傳送乙個請求說又要買了,伺服器接收到了你的第乙個非同步請求,你又有非同步請求,非同步請求又不能停止,求伺服器陰影面積?

promise的第二個缺點:promise不設定**函式,丟擲的錯誤無法在外部捕獲

piomise的第三個缺點:處於pending狀態,無法知道進展到哪個狀態

下面乙個經典的案例:用promise寫出ajax,就體現了promise的特點

function

getjson(url)

if (this.status ==200)

else}})

return

promise;

}getjson("/new2").then(function

(value),

function

(error))

5、es7語法糖async/await

async非同步函式是promise的完成狀態,async函式直接then去獲取狀態改變值,catch來獲取錯誤

await只允許在async內部使用,就是async非同步函式內部想要繼續then,就可以採用await非同步函式,await非同步函式是內部的async非同步函式

async極大精簡了promise的操作   

async  function

asyncfn()

asyncfn()

.then(x =>)

.catch(err => console.log(error))

這是未精簡的promise操作,功能是把最終結果return最外層的promise,但是 用到了多層巢狀,比較複雜

const fn = () =>)

}else

})}

而async非同步函式,直接去return出結果就行,這就是await是async內部async非同步函式

const fn = async () =>

else

}

6、co庫的generator函式

generator函式是乙個非同步函式,只有非同步操作有結果才會交還執行權

generator用到了es6的遍歷iterator的概念,建立乙個指標物件,指向資料結構的起始位置,每次next指向下乙個指標結構成員,直至指向的下乙個結構成員為undefined

generator概念就是,每次遍歷讀用next方法,內部指標從結構頭部指向下乙個結構成員,直至下乙個結構成員為undefined,遇到yield或return時會返回value和done引數,value表示yield或return的值,done表示是否結束 

function *gen(x)

var g = gen(1);

console.log(g.next())

//

yield是遍歷的停止標誌

而generator中的yield*表示 yield* 後面跟著乙個可遍歷的結構

最近的review,讓我對js又有新的認識,js非同步操作是js的核心所在,也是js迷人的地方,async/await和generator都是promise的語法糖,我覺得沒有優劣之分,可能道行太淺,還需刷道,希望業界前輩多多指責我,讓我進步更快。

好了,今天的交流就結束了,下次複習js定時器的記憶體分配等。

js高階操作

window.onload functionjs 是js入口函式,文件載入完畢在執行。while迴圈 1 變數設定初始值 2 語法 while 條件 自增i 自減i for迴圈 語法 for 初始值 條件 增量 陣列就是把一組有關聯的資料放在一起,push在結尾新增資料 pop在結尾刪除資料 spl...

js操作高階

1.物件使用的高階 物件的key為字元型別,value為任意型別 var obj 訪問 obj.name obj name obj person age 物件的屬性可以任意新增與刪除 var ogj 刪除 delete obj.name 新增 obj.age 18 如果age的key已經存在就是修改...

JS中的非同步

hello,日常更新的我 浪 回來了!js中有三座高山 非同步和單執行緒 作用域和閉包 原型原型鏈 今天 浪 的主題是js中的非同步和單執行緒的問題。主要從這三個方面入手 一 什麼是非同步 與同步作比較 二 前端使用非同步的場景 三 非同步和單執行緒 一 什麼是非同步 說非同步之前我們先了解一下同步...