趣味探索promise的秘密

網(wǎng)上也有很多關(guān)于promise的講解歌径,但感覺都停留在理論層面毁嗦,對(duì)于讀者來(lái)說(shuō),看了一遍回铛,似乎已經(jīng)全部明白了狗准,但真要用起來(lái),發(fā)現(xiàn)還是無(wú)從下手茵肃。因此腔长,本文旨在用人話為小伙伴們解釋一下promise到底真正怎么用。
最近的項(xiàng)目里包含了大量的表單交互验残,必然免不了各種異步請(qǐng)求捞附,promise使用相當(dāng)頻繁。我想您没,是時(shí)候來(lái)與小伙伴們分享一下我遇到的各種promise的坑了鸟召。

promise干嘛用的?----一般用于異步操作氨鹏。
為什么能用來(lái)異步操作欧募?----因?yàn)槟艿纫粋€(gè)函數(shù)執(zhí)行完之后執(zhí)行下一個(gè)函數(shù)操作。
懂了嗎仆抵?----懂了
那好跟继,用一個(gè)我看看----額种冬,那個(gè)。还栓。到底怎么寫來(lái)著碌廓。。
你不是都懂了嗎剩盒?----是啊,道理我都懂啊慨蛙,但為什么就是不會(huì)用呢辽聊。。

哈哈期贫,這就是我最初使用promise的深刻感受跟匆,明明那些概念都懂,語(yǔ)法也并不復(fù)雜通砍,可就是實(shí)際用的時(shí)候用不出來(lái)玛臂。如果你也有這種感受,那么封孙,恭喜你迹冤,來(lái)對(duì)地方了,跟著我繼續(xù)探索promise的秘密吧虎忌!

promise和then的配套使用

我們來(lái)想象這么一個(gè)生活情境:

開學(xué)了泡徙,幼兒園里的小朋友們排排坐,老師說(shuō):小朋友們膜蠢,讓我們來(lái)介紹自己的名字好不好呀堪藐,那么,從第一排的小紅開始挑围,依次往下介紹礁竞,好,我們開始吧杉辙!
小紅站起來(lái)說(shuō)模捂,大家好,我叫小紅奏瞬,
接著小強(qiáng)站起來(lái)說(shuō)枫绅,大家好,我叫小強(qiáng)
硼端。
并淋。
接著,輪到小明了珍昨,小明有個(gè)缺點(diǎn)县耽,就是一緊張就口吃句喷,只聽他紅著臉,站起來(lái)說(shuō):大兔毙。唾琼。大瓢娜。递览。大缰犁。禾酱。大堡掏。昭雌。家图毕。盹舞。好叙量。倡蝙。好。绞佩。
還沒說(shuō)完呢寺鸥,后面的急性子小剛就站了起來(lái),說(shuō):大家好品山,我叫小剛
說(shuō)完胆建,小剛后面的同學(xué)就接著站了起來(lái),繼續(xù)介紹自己谆奥。
最后眼坏,最后一排的同學(xué)也介紹完自己,坐下去了酸些。此時(shí)宰译,到家聽到小明的聲音:我叫。魄懂。叫沿侈。。叫市栗。缀拭。。叫填帽。蛛淋。叫。篡腌。
此時(shí)褐荷,老師也不耐煩了,說(shuō):行了嘹悼,小明叛甫,坐下吧
可憐的小明层宫,就這樣,連一個(gè)自我介紹都沒有完成其监。萌腿。。

好了抖苦,親毁菱,記住上面的故事了嗎?我們開始學(xué)習(xí)promise锌历。本來(lái)大家都好好的鼎俘,按順序自我介紹,挺好辩涝。但畢竟人生不如意十之八九,誰(shuí)能想到小明有些口吃呢勘天,所以小剛就搶著自我介紹了怔揩,你可能想說(shuō),這都怪小剛脯丝,可人家小剛還委屈呢商膊,老師說(shuō)的,按照座位來(lái)的宠进,既然小明已經(jīng)開始自我介紹了晕拆,那我就開始嘛,誰(shuí)知道他這么慢呢材蹬。
對(duì)实幕,小明就是這個(gè)異步操作,異步請(qǐng)求和接受服務(wù)器相應(yīng)都是需要時(shí)間的堤器,但是人家正常的js程序不管這些昆庇,一條語(yǔ)句執(zhí)行了,下一條語(yǔ)句就會(huì)接著執(zhí)行闸溃,不會(huì)去管上一條語(yǔ)句又沒有完成整吆,程序員你也沒說(shuō)要必須等上一條語(yǔ)句執(zhí)行完才能執(zhí)行下一條啊。
這樣的問題在哪里呢辉川,問題在最后表蝙,老師統(tǒng)計(jì)班上同學(xué)姓名的時(shí)候,會(huì)直接把小明漏掉乓旗,因?yàn)榻y(tǒng)計(jì)的時(shí)候府蛇,他都沒有自我介紹完啊寸齐!也就是說(shuō)欲诺,你后面的語(yǔ)句需要用到前面異步的返回值的時(shí)候抄谐,就會(huì)接收不到!
故事還沒完呢扰法,接下來(lái)聽第二段:

第二年蛹含,小明班上換了一個(gè)班主任,這回小明學(xué)聰明了塞颁,提前就跟老師說(shuō)明了他的情況浦箱,于是老師想了個(gè)辦法。
老師說(shuō)祠锣,同學(xué)們酷窥,我們今年的自我介紹,換一種方式伴网,每一位同學(xué)在自我介紹之前蓬推,必須要先說(shuō)出前一位同學(xué)的名字,才能進(jìn)行自我介紹澡腾,這樣小剛就算再性急沸伏,也必須要等小明自我介紹完了才能開始自我介紹。
多么聰明的老師啊动分,這樣毅糟,任何同學(xué),都能做完一個(gè)完整的自我介紹了澜公!

老師的做法姆另,就是promise。后一個(gè)同學(xué)必須要等錢一個(gè)同學(xué)說(shuō)完坟乾,因?yàn)樗枰耙粋€(gè)同學(xué)的名字迹辐。來(lái)看promise的語(yǔ)法:

new Promise((resolve,reject)=>{
// dosomething(異步操作);
    resolve(value)
})

把老師的做法翻譯成js語(yǔ)句就是這樣:

var m=new Promise((resolve,reject)=>{
    console.log('小明開始自我介紹')
    setTimeout(()=>{//用定時(shí)器模擬的異步操作(小明口吃)
        var name='小明'
        resolve(name)
    },3000)
})
m.then(model=>{
    var preName=model
    var name='小剛'
    console.log(preName)
    console.log(name)
})

執(zhí)行結(jié)果如下:

QQ截圖20170208152427.jpg

你會(huì)發(fā)現(xiàn),不光是小明在等待了3秒后才打印出來(lái)糊渊,小剛也一樣是等待了3秒后才打印出來(lái)右核,這充分說(shuō)明了promise的特點(diǎn),同時(shí)我都不用再解釋渺绒,相信then的用法相信小伙伴們也能很輕易的學(xué)會(huì)了贺喝!

Promise.all的應(yīng)用場(chǎng)合

接下來(lái),說(shuō)說(shuō)Promise.all的應(yīng)用場(chǎng)合宗兼,同樣躏鱼,上故事:

開學(xué)第二天,老師需要統(tǒng)計(jì)學(xué)生們的個(gè)人信息殷绍,于是讓班長(zhǎng)小紅給每人發(fā)了一張個(gè)人信息表染苛,讓他們填寫,并囑咐她,一定要等所有的同學(xué)都填完了茶行,再收上來(lái)躯概。小紅心里偷偷的笑了,肯定老師已經(jīng)知道小華寫字特別慢了畔师。娶靡。

天啊,這到底是怎樣一個(gè)班級(jí)看锉,口吃的姿锭、寫字慢的。伯铣。呻此。為老師默哀一秒鐘。腔寡。焚鲜。
咳咳,說(shuō)正事放前。其實(shí)老師的囑咐恃泪,便是Promise.all的做法,Promise.all語(yǔ)法如下:

Promise.all(arr)

arr是一個(gè)包含Promise對(duì)象元素的數(shù)組犀斋,可能這么說(shuō)還是有點(diǎn)抽象,那接下來(lái)把老師的做法翻譯成js:

var xiaoming=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaoming',age:'5'}
        resolve(info)
    },2000)
})
var xiaogang=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaogang',age:'6'}
        resolve(info)
    },1000)
})
var xiaohua=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaohua',age:'7'}
        resolve(info)
    },5000)
})
var arr=[xiaoming,xiaogang,xiaohua]
Promise.all(arr).then(model=>{
    console.log(model)
})

結(jié)果如你所料情连,在等待了5秒后叽粹,控制臺(tái)打印出了三個(gè)人的信息:

QQ截圖20170208154348.png

Promise.all的用法也就一目了然了,它會(huì)讓多個(gè)互不影響的Promise里的語(yǔ)句同時(shí)執(zhí)行却舀,等待所有的Promise語(yǔ)句全部執(zhí)行完虫几,然后執(zhí)行then里的操作,返回給then的model是所有Promise里的resolve的值組成的一個(gè)數(shù)組挽拔。

promise的異常處理

同志們辆脸,接下來(lái),嘿嘿嘿螃诅,繼續(xù)講故事:

在填寫個(gè)人信息的時(shí)候啡氢,小智的通知看到他填的年齡是8歲,于是指著他說(shuō):哈哈哈术裸,你個(gè)智障倘是,8歲還讀幼兒園。袭艺。搀崭。小智惱羞成怒,和同桌大打了一架猾编,打架中途瘤睹,個(gè)人信息表也被同桌給撕了升敲。這下子,班長(zhǎng)小紅苦惱了轰传,老師可是說(shuō)驴党,要等每個(gè)人都寫完再把他們所有的信息表收上來(lái),這可怎么辦啊绸吸。鼻弧。。

好了锦茁,我們暫且先不要管這個(gè)班里為什么會(huì)有這么多奇葩攘轩。我們來(lái)看邏輯,本來(lái)異步請(qǐng)求正常執(zhí)行完码俩,接下來(lái)就執(zhí)行then里的resolve度帮,那現(xiàn)在如果向服務(wù)器請(qǐng)求失敗了,又會(huì)怎么樣呢稿存,總不能還是執(zhí)行吧笨篷,直接看代碼:

var xiaozhi=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaozhi',age:'8'}
        var reason='打架,小智的信息表被撕了'
        if(reason){
            info=null
            reject(reason) 
        }else{
            resolve(info)
        }
        
    },5000)
})
xiaozhi.then(model=>{
    console.log(model)
},error=>{
    console.log('提交個(gè)人信息表失敗')
    console.log('原因是'+error)
})

這段代碼執(zhí)行結(jié)果如下:

Paste_Image.png

小智因?yàn)檫@個(gè)事情,被老師狠狠的批評(píng)了一頓瓣履,他不禁想率翅,如果時(shí)光能夠倒流,當(dāng)初沒有打這個(gè)架該多好啊袖迎。小伙伴們冕臭,你應(yīng)該明白我的意思了,不打架燕锥,reason就是undefined,就會(huì)進(jìn)入else里的語(yǔ)句辜贵,就能正常的輸出給then的model了。實(shí)際情況正是如此归形,你很難保證你的請(qǐng)求就一定能夠成功響應(yīng)托慨,如果沒有成功請(qǐng)求到數(shù)據(jù),你就應(yīng)該攔住它暇榴,執(zhí)行請(qǐng)求失敗的情況的語(yǔ)句厚棵。
可能有的小伙伴會(huì)錯(cuò)誤的理解為,失敗那不就是語(yǔ)句執(zhí)行錯(cuò)誤嗎蔼紧?這里一定要主要窟感,這里的失敗是指異步請(qǐng)求的失敗,并不是js語(yǔ)句的執(zhí)行失敗歉井。換句話說(shuō)柿祈,這里的失敗,是你自己定義的失敗,如果你非要把請(qǐng)求成功定義為失敗躏嚎,那也會(huì)照樣進(jìn)入reject蜜自,而不會(huì)執(zhí)行resolve。

Promise.all的異常處理

Promise.all的異常處理是什么樣子呢卢佣,看代碼:

var xiaoming=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaoming',age:'5'}
        resolve(info)
    },2000)
})
var xiaogang=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaogang',age:'6'}
        resolve(info)
    },1000)
})
var xiaohua=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaohua',age:'7'}
        resolve(info)
    },5000)
})
var xiaozhi=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        var info={name:'xiaozhi',age:'8'}
        var reason='打架,小智的信息表被撕了'
        if(reason){
            info=null
            reject(reason) 
        }else{
            resolve(info)
        }
    },1000)
})

var arr=[xiaoming,xiaogang,xiaohua,xiaozhi]
Promise.all(arr).then(model=>{
    console.log(model)
},error=>{
    console.log('收上來(lái)失敗')
})

執(zhí)行結(jié)果如下:

Paste_Image.png

1秒的時(shí)候重荠,打印出“收上來(lái)失敗”這句話,就好比

小紅把除了小智的其他人的信息表全部收上來(lái)了給老師虚茶,老師一看戈鲁,少了小智的,說(shuō):少了小智的嘹叫,重新發(fā)下去吧婆殿,這信息表不全,收上來(lái)我也不要罩扇。

看到了吧婆芦,Promise.all就是保證所有的Promise都是成功的,只要有一個(gè)失敗喂饥,它就執(zhí)行reject消约,并且其他的哪怕是成功的Promise結(jié)果也都全部舍棄。這叫员帮,一個(gè)都不能少或粮!

怎么樣,小伙伴們捞高,看了這篇文章被啼,是否如同剝開了Promise身上的那層薄紗,將她看了個(gè)仔細(xì)呢(咳咳棠枉,別想歪。泡挺。辈讶。)。

如果覺得文章不錯(cuò)娄猫,請(qǐng)?jiān)谙路近c(diǎn)贊支持我哦贱除!

參考資料

MDN官方文檔--Promise

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市媳溺,隨后出現(xiàn)的幾起案子月幌,更是在濱河造成了極大的恐慌,老刑警劉巖悬蔽,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扯躺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)录语,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門倍啥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人澎埠,你說(shuō)我怎么就攤上這事虽缕。” “怎么了蒲稳?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵氮趋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我江耀,道長(zhǎng)剩胁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任决记,我火速辦了婚禮摧冀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘系宫。我一直安慰自己索昂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布扩借。 她就那樣靜靜地躺著椒惨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪潮罪。 梳的紋絲不亂的頭發(fā)上康谆,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音嫉到,去河邊找鬼沃暗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛何恶,可吹牛的內(nèi)容都是我干的孽锥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼细层,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惜辑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起疫赎,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盛撑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捧搞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抵卫,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狮荔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陌僵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轴合。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖碗短,靈堂內(nèi)的尸體忽然破棺而出受葛,到底是詐尸還是另有隱情,我是刑警寧澤偎谁,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布总滩,位于F島的核電站,受9級(jí)特大地震影響巡雨,放射性物質(zhì)發(fā)生泄漏闰渔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一铐望、第九天 我趴在偏房一處隱蔽的房頂上張望冈涧。 院中可真熱鬧,春花似錦正蛙、人聲如沸督弓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)愚隧。三九已至,卻和暖如春锻全,著一層夾襖步出監(jiān)牢的瞬間狂塘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工鳄厌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荞胡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓了嚎,卻偏偏與公主長(zhǎng)得像泪漂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子新思,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券赘风,享受所有官網(wǎng)優(yōu)惠夹囚,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 11,026評(píng)論 26 95
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券邀窃,享受所有官網(wǎng)優(yōu)惠荸哟,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 8,681評(píng)論 0 29
  • 什么是Promise fetchX() 和fetchY() 是直接調(diào)用的假哎,它們的返回值(promise!)被傳給a...
    xpwei閱讀 2,550評(píng)論 0 6
  • 00、前言Promise 是異步編程的一種解決方案劣砍,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大惧蛹。它由社區(qū)...
    夜幕小草閱讀 2,133評(píng)論 0 12
  • 怎么說(shuō)呢,寫作讓我有了個(gè)“出口”刑枝!不開心了寫寫香嗓、有點(diǎn)事情寫寫思緒就擼清了、寫作讓我自己更欣賞自己了装畅!這點(diǎn)我比...
    原生家庭的痛閱讀 154評(píng)論 0 0