js 異步的幾種解決方案

為什么會(huì)出現(xiàn)異步

js是一門(mén)為瀏覽器而誕生的語(yǔ)言,發(fā)展到現(xiàn)在壶谒,js已經(jīng)不僅僅只在瀏覽器上運(yùn)行了仆救,服務(wù)端也可以運(yùn)行js抒和,像node。而js最初設(shè)計(jì)是單線程彤蔽,也就是說(shuō)會(huì)一行一行的執(zhí)行摧莽,下面需要等待上面代碼執(zhí)行完畢,也就是說(shuō)在特定的時(shí)刻只能做特定的事情顿痪,阻塞其他代碼的執(zhí)行镊辕。

常用的異步例如網(wǎng)絡(luò)請(qǐng)求、讀取文件等蚁袭。

異步解決方案

了解javascript為什么會(huì)出現(xiàn)異步征懈,那么我們?cè)撛趺慈ソ鉀Q異步呢?如何書(shū)寫(xiě)日常工作中的工程代碼呢揩悄?javascript的演變中出現(xiàn)了如下幾種解決方案卖哎。

callback

一般在網(wǎng)絡(luò)請(qǐng)求中我們并不知道服務(wù)端啥時(shí)候返回結(jié)果,在這個(gè)等待的過(guò)程中删性,我們不能讓頁(yè)面一直卡頓或是不能操作的狀態(tài)亏娜,這樣會(huì)給用戶很不好的體驗(yàn)感覺(jué),我們又需要在服務(wù)端返回結(jié)果的時(shí)候來(lái)進(jìn)行相應(yīng)的操作或是數(shù)據(jù)更新镇匀。于是回調(diào)函數(shù)就成為異步的第一個(gè)解決方案照藻,如下:

$.ajax({

? ? "url": "",

? ? success: function(data){

? ? ?//函數(shù)返回成功需要進(jìn)行的操作或數(shù)據(jù)更新

? ? },

? ? error: function(err){

? ? //函數(shù)返回失敗需要進(jìn)行的操作或提示

? ?}

})

這是在jq中我們非常熟悉的一個(gè)操作,當(dāng)我們?nèi)フ?qǐng)求服務(wù)端時(shí)汗侵,不管成功或失敗幸缕,服務(wù)端都會(huì)返回一個(gè)結(jié)果群发,success和error函數(shù)就是一個(gè)callback函數(shù),不管成功或是失敗发乔,我們都能進(jìn)行相應(yīng)的操作或是提示熟妓,在網(wǎng)絡(luò)請(qǐng)求的過(guò)程中,并不影響用戶對(duì)別的操作(除非不想讓用戶操作栏尚,必須要等待這個(gè)操作完成)起愈,當(dāng)服務(wù)端返回?cái)?shù)據(jù)時(shí),我們可以通過(guò)callback接收到译仗,這個(gè)時(shí)候我們?cè)龠M(jìn)行相應(yīng)的操作抬虽。

Promise

在callback中,如果當(dāng)前網(wǎng)絡(luò)請(qǐng)求需要依賴前一個(gè)網(wǎng)絡(luò)請(qǐng)求纵菌,我們就有可能掉進(jìn)回調(diào)地獄阐污,

如圖:

于是promise的出現(xiàn)為我們解決了這個(gè)問(wèn)題。promise是在ES6中被統(tǒng)一規(guī)范,由瀏覽器直接支持,promise為一諾千金的意思咱圆,意思是在將來(lái)不管這個(gè)狀態(tài)成功或是失敗笛辟,都將返回一個(gè)結(jié)果。

promise有三種狀態(tài):

等待中? pending序苏;

已完成? fulfilled手幢;

已拒絕? reject;

let test = new promise(resolve,reject){

? ? ? if(success){

? ? ? ? ?resolve();

? ? ? }else{

? ? ? ? reject();

? ? ? }

? }

test()

.then(res => {

? ?//成功時(shí)返回函數(shù)

})

.catch(err => {

? //失敗時(shí)返回函數(shù)

})

Generator

我們希望以同步方式寫(xiě)異步代碼忱详,可以使邏輯清晰围来,代碼簡(jiǎn)潔,為了實(shí)現(xiàn)這種目的踱阿,我們又演進(jìn)出generator方案管钳,

function * add(x){

? ?yield? x + 50;

? ?yield x + 100;

? ?return x + 150;

}

let? test = add(5);

test.next(); //done: true , value: 55

test.next(); //done: true , value: 105

test.next(); //done: true , value: 155

如上钦铁,genertor與普通函數(shù)區(qū)別不大软舌,function后面加了一個(gè)*,

首先定義了一個(gè)test = add(5),函數(shù)沒(méi)有執(zhí)行牛曹,只是生成了一個(gè)genertor對(duì)象佛点,函數(shù)屬于暫停狀態(tài),只有當(dāng)執(zhí)行.next()時(shí)黎比,才會(huì)激活暫停狀態(tài)超营,開(kāi)始執(zhí)行內(nèi)部代碼,遇到第一個(gè)yield才會(huì)返回執(zhí)行結(jié)果阅虫,并記住上下文演闭,暫停,交出控制權(quán)颓帝,再次執(zhí)行米碰,找到第二個(gè)yield窝革,并重復(fù)上述步驟

function* Fn(){

? var result = yield ajax(url);

var result1 = yield ajax(url1);

}

let F = Fn();

var result = F.next();

result.value

.then(res => {

? ?F.next();

})

.catch(err => {

})

如上 封裝一個(gè)ajax異步吕座,定義一個(gè)genertor對(duì)象虐译,執(zhí)行請(qǐng)求交出控制權(quán),根據(jù)返回結(jié)果執(zhí)行第二個(gè)ajax請(qǐng)求

asnyc/await

ES7的asnyc/await號(hào)稱是異步的終極解決方案吴趴,讓我們以同步的方式來(lái)書(shū)寫(xiě)異步代碼漆诽,這樣看起來(lái)更簡(jiǎn)潔,邏輯更清晰锣枝。

比如微信小程序煩人的異步:

const Login =? data => {?

? return new Promise( (resolve, reject) => {?

? ? wx.login({?

? ? ? success: res => {?

? ? ? ? ?resolve(res);

? ? ? ?},?

? ? ? ?fail: err => {??

? ? ? ? ? reject(err);?

? ? ? ? }?

? ? ? })?

? ?})?

}

const getUserInfos = data => {

? return new Promise((resolve,reject){

? ? wx.getUserInfo({

success: res => {

? ? ? ?resolve(res);

? ? ? },

? ? ?fail: err => {?

? ? ? ?reject(err);

? ? ?}?

? ? })

? })

}

const sendCode = data = > {

? return new Promise((resolve,reject){

? ? ?wx.request({

? ? ? ?url: '',

? ? ? ?success: res=> {

? ? ? ? ? ?resolve(res);

? ? ? ?},

? ? ? ?fail: err => {

? ? ? ? ? reject(err);

? ? ? ?}

? ? ?})

? })

}

以上就是封裝好的微信登錄過(guò)程中的獲取code userInfo 和發(fā)送ajax請(qǐng)求的幾個(gè)函數(shù)厢拭,

然后

asycn function getLogin(){

?try {

? let result_login? =? await Login();

? let result_userInfo = await getUserInfos();

result_userInfo['code'] = result_login['code'];

? let result_sendCode = await sendCode(result_userInfo );

? return result_sendCode;

?}catch(err){

?console.log(err);

}

}

getLogin()

.then(res => {

})

.catch(err => {

}

async與genertor的寫(xiě)法類似,具備更好的語(yǔ)義撇叁,并且返回的是promise

作者:lzksdxh

鏈接:https://juejin.im/post/5af8f706f265da0b8f62a7d1

來(lái)源:掘金

著作權(quán)歸作者所有蚪腐。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處税朴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末回季,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子正林,更是在濱河造成了極大的恐慌泡一,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觅廓,死亡現(xiàn)場(chǎng)離奇詭異鼻忠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杈绸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)帖蔓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瞳脓,你說(shuō)我怎么就攤上這事塑娇。” “怎么了劫侧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵埋酬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我烧栋,道長(zhǎng)写妥,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任审姓,我火速辦了婚禮珍特,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘魔吐。我一直安慰自己扎筒,他們只是感情好呼猪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著砸琅,像睡著了一般宋距。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上症脂,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天谚赎,我揣著相機(jī)與錄音,去河邊找鬼诱篷。 笑死壶唤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棕所。 我是一名探鬼主播闸盔,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼琳省!你這毒婦竟也來(lái)了迎吵?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤针贬,失蹤者是張志新(化名)和其女友劉穎击费,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體桦他,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔫巩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了快压。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圆仔。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蔫劣,靈堂內(nèi)的尸體忽然破棺而出坪郭,到底是詐尸還是另有隱情,我是刑警寧澤拦宣,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布截粗,位于F島的核電站,受9級(jí)特大地震影響鸵隧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜意推,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一豆瘫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菊值,春花似錦外驱、人聲如沸育灸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)磅崭。三九已至,卻和暖如春瓦哎,著一層夾襖步出監(jiān)牢的瞬間砸喻,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蒋譬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留割岛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓犯助,卻偏偏與公主長(zhǎng)得像癣漆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子剂买,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 弄懂js異步 講異步之前惠爽,我們必須掌握一個(gè)基礎(chǔ)知識(shí)-event-loop。 我們知道JavaScript的一大特點(diǎn)...
    DCbryant閱讀 2,711評(píng)論 0 5
  • 異步編程對(duì)JavaScript語(yǔ)言太重要瞬哼。Javascript語(yǔ)言的執(zhí)行環(huán)境是“單線程”的疆股,如果沒(méi)有異步編程,根本...
    呼呼哥閱讀 7,311評(píng)論 5 22
  • Promise 對(duì)象 Promise 的含義 Promise 是異步編程的一種解決方案倒槐,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,706評(píng)論 1 56
  • 你不知道JS:異步 第三章:Promises 接上篇3-1 錯(cuò)誤處理(Error Handling) 在異步編程中...
    purple_force閱讀 1,398評(píng)論 0 2
  • 定好鬧鐘旬痹,明天要去上班了。
    百香小趣閱讀 1,166評(píng)論 0 49