日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
還在找什么,JavaScript的異步編程解決方案全在這里了

阿里巴巴前端工程師逸翾對JavaScript中的異步編程進(jìn)行了詳細(xì)講解。JavaScript的特點(diǎn)就是單線程,本文首先對單線程異步的原理進(jìn)行了解讀,接著著重分析了JavaScript異步解決方案,詳述了Callback、Promise、Generator、Async/Await的特性和使用原理。

你所需要的網(wǎng)站建設(shè)服務(wù),我們均能行業(yè)靠前的水平為你提供.標(biāo)準(zhǔn)是產(chǎn)品質(zhì)量的保證,主要從事成都網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、高端網(wǎng)站設(shè)計(jì)、網(wǎng)頁制作、做網(wǎng)站、建網(wǎng)站。創(chuàng)新互聯(lián)公司擁有實(shí)力堅(jiān)強(qiáng)的技術(shù)研發(fā)團(tuán)隊(duì)及素養(yǎng)的視覺設(shè)計(jì)專才。

以下是精彩視頻內(nèi)容整理:

單線程異步

JavaScript語言的一大特點(diǎn)就是單線程,在某個(gè)特定的時(shí)刻只有特定的代碼能夠被執(zhí)行,并阻塞其它的代碼,也就是說,同一個(gè)時(shí)間只能做一件事。

常用的異步操作最主要有網(wǎng)絡(luò)請求,請求會(huì)有響應(yīng)時(shí)間,在響應(yīng)結(jié)果回來之前要處理其它事情;IO操作,比如讀取某個(gè)文件,在此過程中做其它事情;定時(shí)函數(shù)。

異步是由瀏覽器的兩個(gè)或以上常駐線程共同完成,列如異步請求:JS執(zhí)行線程發(fā)起異步請求,瀏覽器開一條新的http請求來執(zhí)行請求,當(dāng)監(jiān)視到請求已完成,它會(huì)把函數(shù)插入到JS執(zhí)行隊(duì)列的尾部等待處理。

通過如圖所示定時(shí)函數(shù)實(shí)例,可以看出異步處理過程。先是打印一個(gè)1,然后執(zhí)行setTimeout函數(shù),約定在0秒后再打印一個(gè)2,然后打印一個(gè)3,執(zhí)行結(jié)果為先打印1,再打印3,***再打印2,說明整個(gè)過程已經(jīng)發(fā)生異步過程。

Javascript有一個(gè)主要的執(zhí)行主線程,但是setTimeout、IO操作、網(wǎng)絡(luò)異步請求等都會(huì)有一個(gè)回調(diào)函數(shù),這些操作都是通過瀏覽器API實(shí)現(xiàn)的,當(dāng)定時(shí)器時(shí)間到了或者請求結(jié)果回來時(shí),會(huì)將回調(diào)函數(shù)push到一個(gè)javascript任務(wù)隊(duì)列中,當(dāng)javascript主線程任務(wù)執(zhí)行完畢后,才會(huì)從任務(wù)隊(duì)列中繼續(xù)拿等待代碼再執(zhí)行。具體流程總結(jié)如下:

所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。

主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。

一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。

主線程不斷重復(fù)上面的第三步。

異步解決方案

了解了Javascript單線程與異步關(guān)系,如何書寫日常工作中的工程代碼呢?怎樣能在異步請求結(jié)束后執(zhí)行特定方法?目前,javascript異步編程經(jīng)歷了幾個(gè)階段,且在不斷演進(jìn)。

Callback

最開始是回調(diào)函數(shù),當(dāng)事件完成后執(zhí)行回調(diào)函數(shù),相當(dāng)于完成異步操作。我們可以像使用變量一樣使用函數(shù),作為另一個(gè)函數(shù)的參數(shù),在另一個(gè)函數(shù)中作為返回結(jié)果,在另一個(gè)函數(shù)中調(diào)用它。當(dāng)我們作為參數(shù)傳遞一個(gè)回調(diào)函數(shù)給另一個(gè)函數(shù)時(shí),我們只傳遞了這個(gè)函數(shù)的定義,并沒有在參數(shù)中執(zhí)行它。當(dāng)函數(shù)擁有了在參數(shù)中定義的回調(diào)函數(shù)后,它可以在任何時(shí)候調(diào)用(也就是回調(diào))它。

我們在工作中最長接觸的就是發(fā)送Ajax異步請求,在***個(gè)請求發(fā)送完后,用它的參數(shù)處理第二個(gè)請求,再用第二個(gè)請求的參數(shù)請求第三個(gè),三層嵌套代碼如圖所示。

如圖所示為mongoDB在node.js中的實(shí)例,嵌套了六層。當(dāng)多個(gè)異步事務(wù)多級依賴時(shí),回調(diào)函數(shù)會(huì)形成多級的嵌套,代碼變成金字塔型結(jié)構(gòu)。雖然能解決異步問題,但這使得代碼得看難懂,更使得調(diào)試、重構(gòu)的過程充滿風(fēng)險(xiǎn)。

Promise

Promise比傳統(tǒng)解決方案更加合理和強(qiáng)大,是更加好的異步解決方案,promise對象有以下四個(gè)特點(diǎn):

  1. promise 可能有三種狀態(tài):等待(pending)、已完成(resolved)、已拒絕(rejected)。
  2. promise 的狀態(tài)只可能從“等待”轉(zhuǎn)到“完成”態(tài)或者“拒絕”態(tài),不能逆向轉(zhuǎn)換,同時(shí)“完成”態(tài)和“拒絕”態(tài)不能相互轉(zhuǎn)換。
  3. promise對象必須實(shí)現(xiàn)then方法,而且then必須返回一個(gè)promise ,同一個(gè) promise 的then可以調(diào)用多次(鏈?zhǔn)剑?,并且回調(diào)的執(zhí)行順序跟它們被定義時(shí)的順序一致。
  4. then方法接受兩個(gè)參數(shù),***個(gè)參數(shù)是成功時(shí)的回調(diào),在 promise 由“等待”態(tài)轉(zhuǎn)換到“完成”態(tài)時(shí)調(diào)用,另一個(gè)是失敗時(shí)的回調(diào),在 promise 由“等待”態(tài)轉(zhuǎn)換到“拒絕”態(tài)時(shí)調(diào)用

如圖所示,左側(cè)創(chuàng)建promise對象,隔2000秒后執(zhí)行,***返回promise對象。Promise有立即執(zhí)行性,當(dāng)創(chuàng)建完對象后,在已完成或已拒絕之前代碼都會(huì)執(zhí)行一遍。右側(cè)為打印結(jié)果,可以看到創(chuàng)建promise對象被打印出來,并成功生成promise對象,當(dāng)執(zhí)行then時(shí),此時(shí)已經(jīng)返回成功狀態(tài),所以一直執(zhí)行成功的回調(diào)函數(shù)。

那么,promise如何解決異步問題的呢?又有哪些特點(diǎn)呢?具體如下:

代碼看起來更加符合邏輯、可讀性更強(qiáng)。

Promise并沒有改變JS異步執(zhí)行的本質(zhì),從寫法上甚至還能看到一點(diǎn)點(diǎn)callback的影子。

如圖所示為鏈?zhǔn)秸{(diào)用方式,***個(gè)請求成功后,就去執(zhí)行下一個(gè),如果任何一個(gè)請求未成功,直接catch掉error,并打印出來。

Generator

我們希望以同步方式寫異步代碼,可以使邏輯更加清晰,代碼量減少更多。為了實(shí)現(xiàn)這種目標(biāo),我們又演進(jìn)出generator解決方案。

Generator函數(shù)很特殊,理解起來比promise和callback更加難,從語法上將,generator具備以下特質(zhì):

  1. 定義Generator時(shí),需要使用function*。
  2. 使用時(shí)生成一個(gè)Generator對象。
  3. 執(zhí)行.next()激活暫停狀態(tài),開始執(zhí)行內(nèi)部代碼,直到遇到y(tǒng)ield,返回此時(shí)執(zhí)行的結(jié)果,并記住此時(shí)執(zhí)行的上下文,暫停。
  4. 再次執(zhí)行.next()時(shí)重復(fù)第三步。

如圖所示,首先定義了test=add(5),函數(shù)并沒有執(zhí)行,只是生成了一個(gè)generator對象,函數(shù)屬于暫停狀態(tài),只有當(dāng)執(zhí)行.next()時(shí),才會(huì)激活暫停狀態(tài),開始執(zhí)行內(nèi)部代碼,直到遇到***個(gè)yield才會(huì)返回執(zhí)行結(jié)果,并記住上下文,暫停,交出控制權(quán)。再次執(zhí)行.next()時(shí),找到第二個(gè)yield,再次記住上下文,暫停,交出控制權(quán),依此重復(fù)。

如圖所示,封裝一個(gè)異步任務(wù),定義一個(gè)generator對象,執(zhí)行請求后交出控制權(quán),通過promise判斷是否要繼續(xù)執(zhí)行。在異步事件發(fā)生后,首先將控制權(quán)交給別人,讓程序執(zhí)行其它代碼,當(dāng)異步事件完成后,將控制權(quán)搶回來,繼續(xù)執(zhí)行其它操作。Generator需要一個(gè)自動(dòng)執(zhí)行器配合使用,實(shí)現(xiàn)正常思維下的異步處理,有了自動(dòng)執(zhí)行器,異步請求可以用同步的方式寫異步代碼,直接將請求全部寫在一起。

通過進(jìn)一步的演進(jìn),async和await函數(shù)應(yīng)運(yùn)而生。它們的個(gè)性特征如下:

  1. async 表示這是一個(gè)async函數(shù),而await只能在這個(gè)函數(shù)里面使用。
  2. await 表示在這里等待await后面的操作執(zhí)行完畢,再執(zhí)行下一句代碼。
  3. await 后面緊跟著的***是一個(gè)耗時(shí)的操作或者是一個(gè)異步操作。
  4. await后面必須是一個(gè)Promise對象,如果不是會(huì)被轉(zhuǎn)化為一個(gè)已完成狀態(tài)的Promise

Async與generator的寫法類似,本質(zhì)上是generator的語法糖。其內(nèi)置執(zhí)行器,具備更好的語義,更廣的適用性。并且返回值是Promise。


網(wǎng)頁名稱:還在找什么,JavaScript的異步編程解決方案全在這里了
文章轉(zhuǎn)載:http://www.5511xx.com/article/dphssdd.html