日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

淺談JavaScript中的異步處理

瀏覽:223日期:2023-11-12 14:31:40

整理于互聯(lián)網(wǎng)

在 JavaScript 的世界中,所有代碼都是單線程執(zhí)行的 由于這個(gè)“缺陷”,導(dǎo)致 JavaScript 的所有網(wǎng)絡(luò)操作,瀏覽器事件,都必須是異步執(zhí)行。異步執(zhí)行可以用回調(diào)函數(shù)實(shí)現(xiàn) 異步操作會(huì)在將來(lái)的某個(gè)時(shí)間點(diǎn)觸發(fā)一個(gè)函數(shù)調(diào)用 主流的異步處理方案主要有:回調(diào)函數(shù) (CallBack) 、 Promise 、 Generator 函數(shù)、 async/await 。 一、回調(diào)函數(shù)(CallBack) 這是異步編程最基本的方法 假設(shè)我們有一個(gè) getData 方法,用于異步獲取數(shù)據(jù),第一個(gè)參數(shù)為請(qǐng)求的 url 地址,第二個(gè)參數(shù)是回調(diào)函數(shù),如下:

function getData(url, callBack){ // 模擬發(fā)送網(wǎng)絡(luò)請(qǐng)求 setTimeout(()=> {// 假設(shè) res 就是返回的數(shù)據(jù)var res = { url: url, data: Math.random()}// 執(zhí)行回調(diào),將數(shù)據(jù)作為參數(shù)傳遞callBack(res) }, 1000)} 我們預(yù)先設(shè)定一個(gè)場(chǎng)景,假設(shè)我們要請(qǐng)求三次服務(wù)器,每一次的請(qǐng)求依賴上一次請(qǐng)求的結(jié)果,如下:

getData(’/page/1?param=123’, (res1) => { console.log(res1) getData(`/page/2?param=${res1.data}`, (res2) => {console.log(res2)getData(`/page/3?param=${res2.data}`, (res3) => { console.log(res3)}) })})

通過(guò)上面的代碼可以看出,第一次請(qǐng)求的 url 地址為: /page/1?param=123 ,返回結(jié)果為 res1 。

第二個(gè)請(qǐng)求的 url 地址為: /page/2?param=${res1.data} ,依賴第 一次請(qǐng)求的 res1.data ,返回結(jié)果為 res2`。

第三次請(qǐng)求的 url 地址為: /page/3?param=${res2.data} ,依賴第二次請(qǐng)求的 res2.data ,返回結(jié)果為 res3 。

由于后續(xù)請(qǐng)求依賴前一個(gè)請(qǐng)求的結(jié)果,所以我們只能把下一次請(qǐng)求寫到上一次請(qǐng)求的回調(diào)函數(shù)內(nèi)部,這樣就形成了常說(shuō)的:回調(diào)地獄。

二、發(fā)布/訂閱

我們假定,存在一個(gè)”信號(hào)中心”,某個(gè)任務(wù)執(zhí)行完成,就向信號(hào)中心”發(fā)布”( publish )一個(gè)信號(hào),其他任務(wù)可以向信號(hào)中心”訂閱”( subscribe )這個(gè)信號(hào),從而知道什么時(shí)候自己可以開(kāi)始執(zhí)行。這就叫做”發(fā)布/訂閱模式”(publish-subscribe pattern),又稱”觀察者模式”(observer pattern)

這個(gè)模式有多種實(shí)現(xiàn),下面采用的是Ben Alman的 Tiny Pub/Sub ,這是 jQuery 的一個(gè)插件 首先, f2 向”信號(hào)中心” jQuery 訂閱” done “信號(hào)

jQuery.subscribe('done', f2); f1進(jìn)行如下改寫

function f1(){setTimeout(function(){// f1的任務(wù)代碼jQuery.publish('done');}, 1000);} jQuery.publish('done') 的意思是, f1 執(zhí)行完成后,向”信號(hào)中心 'jQuery 發(fā)布 'done' 信號(hào),從而引發(fā)f2的執(zhí)行。 此外,f2完成執(zhí)行后,也可以取消訂閱( unsubscribe )

jQuery.unsubscribe('done', f2); 這種方法的性質(zhì)與”事件監(jiān)聽(tīng)”類似,但是明顯優(yōu)于后者。因?yàn)槲覀兛梢酝ㄟ^(guò)查看”消息中心”,了解存在多少信號(hào)、每個(gè)信號(hào)有多少訂閱者,從而監(jiān)控程序的運(yùn)行。 三、Promise Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大 所謂 Promise ,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō), Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。 Promise 提供統(tǒng)一的 API ,各種異步操作都可以用同樣的方法進(jìn)行處理 簡(jiǎn)單說(shuō),它的思想是,每一個(gè)異步任務(wù)返回一個(gè) Promise 對(duì)象,該對(duì)象有一個(gè) then 方法,允許指定回調(diào)函數(shù)。 現(xiàn)在我們使用 Promise 重新實(shí)現(xiàn)上面的案例,首先,我們要把異步請(qǐng)求數(shù)據(jù)的方法封裝成 Promise

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 那么請(qǐng)求的代碼應(yīng)該這樣寫

getDataAsync(’/page/1?param=123’) .then(res1=> {console.log(res1)return getDataAsync(`/page/2?param=${res1.data}`) }) .then(res2=> {console.log(res2)return getDataAsync(`/page/3?param=${res2.data}`) }) .then(res3=> {console.log(res3) }) then 方法返回一個(gè)新的 Promise 對(duì)象, then 方法的鏈?zhǔn)秸{(diào)用避免了 CallBack 回調(diào)地獄 但也并不是完美,比如我們要添加很多 then 語(yǔ)句, 每一個(gè) then 還是要寫一個(gè)回調(diào)。 如果場(chǎng)景再?gòu)?fù)雜一點(diǎn),比如后邊的每一個(gè)請(qǐng)求依賴前面所有請(qǐng)求的結(jié)果,而不僅僅依賴上一次請(qǐng)求的結(jié)果,那會(huì)更復(fù)雜。 為了做的更好, async/await 就應(yīng)運(yùn)而生了,來(lái)看看使用 async/await 要如何實(shí)現(xiàn) 四、async/await

getDataAsync 方法不變,如下

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 業(yè)務(wù)代碼如下

async function getData(){ var res1 = await getDataAsync(’/page/1?param=123’) console.log(res1) var res2 = await getDataAsync(`/page/2?param=${res1.data}`) console.log(res2) var res3 = await getDataAsync(`/page/2?param=${res2.data}`) console.log(res3)} 可以看到使用 asyncawait 就像寫同步代碼一樣 對(duì)比 Promise 感覺(jué)怎么樣?是不是非常清晰,但是 async/await 是基于 Promise 的,因?yàn)槭褂?async 修飾的方法最終返回一個(gè) Promise , 實(shí)際上, async/await 可以看做是使用 Generator 函數(shù)處理異步的語(yǔ)法糖,我們來(lái)看看如何使用 Generator 函數(shù)處理異步 五、Generator 首先異步函數(shù)依然是

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 使用 Generator 函數(shù)可以這樣寫

function*getData(){ var res1 = yield getDataAsync(’/page/1?param=123’) console.log(res1) var res2 = yield getDataAsync(`/page/2?param=${res1.data}`) console.log(res2) var res3 = yield getDataAsync(`/page/2?param=${res2.data}`) console.log(res3))} 然后我們這樣逐步執(zhí)行

var g = getData()g.next().value.then(res1=> { g.next(res1).value.then(res2=> {g.next(res2).value.then(()=> { g.next()}) })}) 上面的代碼,我們逐步調(diào)用遍歷器的 next() 方法,由于每一個(gè) next() 方法返回值的 value 屬性為一個(gè) Promise 對(duì)象 所以我們?yōu)槠涮砑?then 方法, 在 then 方法里面接著運(yùn)行 next 方法挪移遍歷器指針,直到 Generator 函數(shù)運(yùn)行完成,實(shí)際上,這個(gè)過(guò)程我們不必手動(dòng)完成,可以封裝成一個(gè)簡(jiǎn)單的執(zhí)行器

function run(gen){ var g = gen() function next(data){var res = g.next(data)if (res.done) return res.valueres.value.then((data) => { next(data)}) } next()}

run 方法用來(lái)自動(dòng)運(yùn)行異步的 Generator 函數(shù),其實(shí)就是一個(gè)遞歸的過(guò)程調(diào)用的過(guò)程。這樣我們就不必手動(dòng)執(zhí)行 Generator 函數(shù)了。 有了 run 方法,我們只需要這樣運(yùn)行 getData 方法

run(getData)

這樣,我們就可以把異步操作封裝到 Generator 函數(shù)內(nèi)部,使用 run 方法作為 Generator 函數(shù)的自執(zhí)行器,來(lái)處理異步。其實(shí)我們不難發(fā)現(xiàn), async/await 方法相比于 Generator 處理異步的方式,有很多相似的地方,只不過(guò) async/await 在語(yǔ)義化方面更加明顯,同時(shí) async/await 不需要我們手寫執(zhí)行器,其內(nèi)部已經(jīng)幫我們封裝好了,這就是為什么說(shuō) async/await 是 Generator 函數(shù)處理異步的語(yǔ)法糖了

來(lái)自:http://blog.poetries.top/2017/08/27/js_cb_promise_generator_async/

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩美女国产精品| 国产成人久久精品一区二区三区| 激情久久99| 国产v日韩v欧美v| 久久国产免费| 亚洲欧美一级| 精品国产黄a∨片高清在线| 日韩欧美二区| 一区免费在线| 青草国产精品久久久久久| 日本视频一区二区| 精品久久亚洲| 蜜臀av免费一区二区三区| 爽好多水快深点欧美视频| 亚洲影视一区二区三区| 国产精品巨作av| 激情五月综合| 91九色综合| 日本高清不卡一区二区三区视频 | 亚洲免费影院| 欧美一区自拍| 欧美日一区二区| 欧美啪啪一区| 亚洲伦乱视频| 亚州av日韩av| 九色porny丨国产首页在线| 综合激情一区| 精品三区视频| 在线看片日韩| 六月婷婷综合| 日韩1区2区日韩1区2区| 日韩在线看片| 91精品国产一区二区在线观看| 亚洲精品成人图区| 日韩国产成人精品| 性欧美xxxx免费岛国不卡电影| 欧美一区二区三区久久精品| 国产一区视频在线观看免费| 日韩激情精品| 欧美一级精品| 美女久久99| 亚洲一区二区三区中文字幕在线观看| 国产成人久久精品麻豆二区 | 日韩成人在线看| 国产99久久| 国产极品模特精品一二| 在线午夜精品| 日韩精品永久网址| 国产欧美日韩一级| 午夜日韩av| 国产成人精品一区二区三区免费| 在线一区二区三区视频| 久久精品91| 免费一区二区三区在线视频| 蜜桃一区二区三区在线| 亚洲第一区色| 国产在线看片免费视频在线观看| 91精品国产一区二区在线观看| 2023国产精品久久久精品双| 国产黄大片在线观看| 国产精品一区亚洲| 免费久久99精品国产| 久久蜜桃av| 97人人精品| 国产精品一区高清| 日韩欧美三区| 蜜桃久久av一区| 国产一区导航| 免费视频一区三区| 久久久久.com| 电影亚洲精品噜噜在线观看| sm捆绑调教国产免费网站在线观看| 国产精品亚洲成在人线| 日韩区一区二| 日韩三区四区| 91麻豆精品激情在线观看最新| 视频一区二区不卡| 好看不卡的中文字幕| 亚洲www啪成人一区二区| 国语对白精品一区二区| 国产激情精品一区二区三区| 国产日韩欧美在线播放不卡| 欧美一区二区三区久久| 日韩欧美2区| 日韩高清欧美激情| 久久国产免费看| 国产精品大片免费观看| 国产精品国码视频| 免费在线欧美黄色| 国模精品一区| 国产伊人久久| 日韩中文首页| 亚洲一级二级| 黄色亚洲大片免费在线观看| 激情欧美国产欧美| 亚洲精品99| 香蕉成人久久| 日韩在线网址| 欧美日韩亚洲一区在线观看| 国产精品网址| 精品三级在线| 麻豆精品蜜桃| 亚洲一区二区网站| 日本欧美在线| 精品国产一区二区三区2021| а√天堂中文在线资源8| 日韩一区二区中文| 伊人影院久久| 中文字幕一区二区精品区| 亚洲一区二区三区四区电影| 一级欧美视频| 国产精品白丝久久av网站| zzzwww在线看片免费| 日本在线精品| 一区二区三区国产盗摄| 久久国产精品色av免费看| 国产精品任我爽爆在线播放| 激情国产在线| 日韩亚洲国产欧美| 欧美一区二区三区久久| 精品欧美日韩精品| 亚洲国产成人精品女人| 欧美在线黄色| 在线手机中文字幕| 波多野结衣一区| 日韩国产高清在线| 国产在线观看www| 免播放器亚洲| 毛片不卡一区二区| 午夜国产精品视频| 欧美亚洲一区二区三区| 水蜜桃精品av一区二区| 亚洲作爱视频| 久久精品天堂| 丝袜国产日韩另类美女| 精品视频一区二区三区在线观看| 国产一区视频在线观看免费| 91国内精品| 婷婷激情久久| 国产日韩亚洲| 欧美亚洲精品在线| 国产精品蜜月aⅴ在线| 久久视频一区| 国产精品日韩精品在线播放| 欧美福利一区| 精品网站aaa| 亚洲精品在线a| 久久精品导航| 久久99蜜桃| 亚洲一区有码| 久久一区二区三区电影| 国产精品久久久久久妇女| 六月天综合网| 欧洲av一区二区| 国产乱码精品一区二区三区四区| 99视频精品全国免费| 国产精品白丝av嫩草影院| 丝袜美腿亚洲色图| 日本欧美不卡| **爰片久久毛片| 日韩视频不卡| 日韩不卡免费高清视频| 久久亚洲国产精品尤物| 日韩和欧美一区二区三区| 99视频精品| 亚洲一级黄色| 亚洲精品一级二级| 精品日韩一区| 国产精品tv| 日韩和欧美一区二区三区| 欧美特黄一区| 久久国产亚洲| 久久男人天堂| 久草精品视频| 国产欧美日韩在线一区二区| 一区二区电影| 性欧美精品高清| 国产一区亚洲| 久久蜜桃精品| 日韩电影二区| 日韩1区在线| 精品欧美视频| 精品五月天堂| 精品国产乱码久久久久久樱花| 88久久精品| 亚洲精品在线二区| 亚洲精品影视| 亚洲不卡视频| 婷婷精品在线观看| 亚洲另类黄色| 亚洲婷婷丁香| 蜜桃视频一区二区| 男女男精品网站| 在线精品一区| 日日摸夜夜添夜夜添国产精品| 亚洲资源在线| 日韩精品免费观看视频| 亚洲欧洲美洲国产香蕉| 日韩三级一区| 国产精品成人国产|