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

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

淺談JavaScript中的異步處理

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

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

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

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

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

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

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

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

二、發(fā)布/訂閱

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

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

jQuery.subscribe('done', f2); f1進(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í)行后,也可以取消訂閱( unsubscribe )

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

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 那么請求的代碼應(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 方法返回一個新的 Promise 對象, then 方法的鏈?zhǔn)秸{(diào)用避免了 CallBack 回調(diào)地獄 但也并不是完美,比如我們要添加很多 then 語句, 每一個 then 還是要寫一個回調(diào)。 如果場景再復(fù)雜一點(diǎn),比如后邊的每一個請求依賴前面所有請求的結(jié)果,而不僅僅依賴上一次請求的結(jié)果,那會更復(fù)雜。 為了做的更好, async/await 就應(yīng)運(yùn)而生了,來看看使用 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 就像寫同步代碼一樣 對比 Promise 感覺怎么樣?是不是非常清晰,但是 async/await 是基于 Promise 的,因?yàn)槭褂?async 修飾的方法最終返回一個 Promise , 實(shí)際上, async/await 可以看做是使用 Generator 函數(shù)處理異步的語法糖,我們來看看如何使用 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() 方法,由于每一個 next() 方法返回值的 value 屬性為一個 Promise 對象 所以我們?yōu)槠涮砑?then 方法, 在 then 方法里面接著運(yùn)行 next 方法挪移遍歷器指針,直到 Generator 函數(shù)運(yùn)行完成,實(shí)際上,這個過程我們不必手動完成,可以封裝成一個簡單的執(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 方法用來自動運(yùn)行異步的 Generator 函數(shù),其實(shí)就是一個遞歸的過程調(diào)用的過程。這樣我們就不必手動執(zhí)行 Generator 函數(shù)了。 有了 run 方法,我們只需要這樣運(yùn)行 getData 方法

run(getData)

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

來自:http://blog.poetries.top/2017/08/27/js_cb_promise_generator_async/

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
中文字幕日本一区二区| 卡一精品卡二卡三网站乱码| 日韩精品视频一区二区三区| 久久国产精品99国产| 欧美精选一区二区三区| 欧美亚洲国产精品久久| 少妇精品导航| 国产高清一区| 久久尤物视频| 国产一区二区三区四区大秀| 国产精品天堂蜜av在线播放| 麻豆精品在线| 91麻豆国产自产在线观看亚洲| 亚洲天堂资源| 99国产精品一区二区| 激情久久婷婷| 亚洲一区欧美二区| 免费在线视频一区| 日韩专区视频网站| 欧美精品三级在线| 精品日韩一区| av免费不卡国产观看| 久久久久亚洲| 综合精品一区| 老鸭窝一区二区久久精品| 另类专区亚洲| 日韩一级欧洲| 国产亚洲精品精品国产亚洲综合| 国产一区二区视频在线看| 亚洲va中文在线播放免费| 亚洲国产成人精品女人| 日韩中文字幕| 日韩a一区二区| 欧美日韩视频一区二区三区| 日韩欧美在线精品| 国产一区二区三区四区五区传媒| 日本免费一区二区三区四区| 亚洲精品中文字幕乱码| 日韩激情一区二区| 97视频热人人精品免费| 亚洲中字黄色| 欧美激情福利| 国产高清一区| 国产精品亚洲片在线播放| 日韩不卡免费高清视频| 一区二区高清| 国产色播av在线| 日韩精品一二区| 精品视频高潮| 美女久久网站| 国产精品毛片一区二区在线看| 久久国产成人午夜av影院宅| 亚洲精品伊人| 日韩中文首页| 日韩av中文字幕一区二区| 国产精品不卡| 亚洲三级在线| 国产videos久久| 综合激情婷婷| 日韩大片在线播放| 日韩精品午夜视频| 香蕉精品久久| 国产精品115| 亚洲综合不卡| 国产专区精品| 天海翼亚洲一区二区三区| 日韩精品免费一区二区三区| 老司机精品久久| 国产精品毛片久久| 日本成人在线不卡视频| 亚洲激情久久| 精品国产亚洲一区二区在线观看| 亚洲一区日韩在线| 精品一区不卡| 日本成人在线一区| 99热国内精品| 成人在线视频免费| 国产调教精品| 亚洲精一区二区三区| 亚洲精品在线观看91| 中文字幕高清在线播放| 国产精选久久| 麻豆精品91| 激情欧美一区二区三区| 久久精品国产亚洲一区二区三区| 天堂av一区| 99re国产精品| 欧美成人基地 | 欧美成人a交片免费看| 日本欧美在线| 噜噜噜躁狠狠躁狠狠精品视频| www.com.cn成人| 精品中文在线| 国产精品亚洲一区二区在线观看| 免费黄网站欧美| 久久精品主播| 国产精品久久久久久久久妇女| 久久gogo国模啪啪裸体| 日本成人中文字幕在线视频| 伊人久久亚洲影院| 成人在线网站| 蜜桃视频在线网站| 精品一区二区三区在线观看视频 | 国产日韩高清一区二区三区在线 | 国产精品115| 亚洲精品伊人| 在线免费观看亚洲| 国产精品日本欧美一区二区三区| 91精品一区国产高清在线gif| 国产精品不卡| 精品一区av| 里番精品3d一二三区| 久久不见久久见免费视频7| 国产欧美一区二区三区国产幕精品| 在线亚洲自拍| 一区三区视频| 午夜亚洲一区| 日韩专区一卡二卡| 人人爽香蕉精品| 热久久久久久久| 亚洲一区二区动漫| 日韩亚洲国产欧美| 亚洲高清二区| 国内精品福利| 亚洲免费精品| 亚洲免费在线| 蜜桃视频在线观看一区| 在线视频亚洲欧美中文| 亚洲精品九九| 午夜精品亚洲| 最新亚洲一区| 美女国产精品| 中文精品电影| 日韩区一区二| 国产日本久久| 久久精品人人| 日韩高清不卡| 中文久久精品| 日韩毛片网站| 国产精品多人| 亚洲精品**中文毛片| 国产色播av在线| 亚洲精品在线观看91| 亚洲无线观看| 青青草国产精品亚洲专区无| 91精品国产自产在线丝袜啪| 欧美激情视频一区二区三区免费 | 精品无人区麻豆乱码久久久| 日韩国产专区| 午夜欧美精品| 日韩av中文字幕一区| 精品视频自拍| 91久久国产| 日韩一区二区三区在线看| 国产精品免费精品自在线观看| 97精品国产福利一区二区三区| 亚洲国产专区校园欧美| 综合国产在线| 91国内精品| а√在线中文在线新版| 樱桃成人精品视频在线播放| 青青草伊人久久| 伊人久久国产| 美女精品在线观看| 国产精品玖玖玖在线资源| 神马午夜在线视频| 国产亚洲一级| 国产精品草草| 国产在线日韩| 欧美亚洲免费| 久久国产直播| 欧美一级一区| 欧美午夜精彩| 蜜桃av一区二区在线观看| 久久不卡国产精品一区二区| 国产99久久| 欧美亚洲tv| 99久久99视频只有精品| 日韩精品久久久久久久软件91| 亚洲最新无码中文字幕久久| 中文字幕日韩欧美精品高清在线| 久久影院一区二区三区| 成人精品天堂一区二区三区| 亚洲综合婷婷| 成人三级高清视频在线看| 老牛国产精品一区的观看方式| 国产精品国产三级在线观看| 91成人精品视频| 国产欧美日韩亚洲一区二区三区| 国产 日韩 欧美一区| 欧美亚洲自偷自偷| 欧美午夜精彩| 麻豆精品视频在线观看视频| 水野朝阳av一区二区三区| 国语精品一区| 日韩国产在线一| 午夜免费一区| 成人国产精品| 日韩av成人高清| 一区免费视频|