Promise 看這個就行了

我們都知道,ES是單線程語言印蔗。所以異步編程對它來說扒最,尤其重要。也可以說是他的核心功能华嘹。

我們常見的異步編程有很多吧趣,比如 回調(diào)函數(shù)?事件監(jiān)聽 發(fā)布訂閱 Promise等除呵。

在早期的時候再菊,我們使用的主要方式是回調(diào)函數(shù),但是當我們有很多回調(diào)函數(shù)需要依賴的時候颜曾,一層套一層纠拔,就會形成回調(diào)地獄

回調(diào)地獄既不利于閱讀也不利于維護泛豪,所以前輩先賢們?yōu)榱私鉀Q這個問題稠诲,做了很多努力。其中Promise 就是其中的一種方案诡曙。

Promise

Promise是一個構造函數(shù)臀叙,返回一個promise對象。該對象有三種狀態(tài)价卤,而且狀態(tài)不可逆劝萤。還有then catch finally 等方法。網(wǎng)上有大量的基礎方法定義慎璧,我們就不在羅列了床嫌。

使用

then的鏈式調(diào)用

我們知道,Promise支持鏈式調(diào)用胸私,那假如中間狀態(tài)變成rejected了厌处,會怎么樣呢。

let p1 = new Promise((resolve,reject) => {
    setTimeout( () => resolve(200) , 1000)
})

p1.then(() => {
        console.log(11)
    })
    .then(() => {
        throw Error(22)
    })
    .then( () => {
        console.log(33)
    })
    .catch(err => {
        console.log('this is error',err)
    })
// 11
// this is error 22

then的回調(diào)函數(shù)返回一個錯誤的時候岁疼,返回的是一個rejected`狀態(tài)的promise阔涉。之后的鏈式調(diào)用被終止了,被最后的catch捕獲到捷绒。

我們知道then 其實是可以接受兩個回調(diào)函數(shù)的瑰排,我們換一個方式猜下執(zhí)行順序是什么呢?

let p1 = new Promise((resolve,reject) => {
    setTimeout( () => resolve(200) , 1000)
})

p1.then(() => {
        console.log(11)
    })
    .then(() => {
        throw Error(22)
    })
    .then( () => {
        console.log(33)
    },fail => {
        console.log('this is from 3rd fn',fail)
    })
    .catch(err => {
        console.log('this is error',err)
    })
    
// 輸出結果為:
//11
// this is from 3rd fn

有沒有想到這個結果疙驾。

從現(xiàn)象看:是因為前面已經(jīng)處理了rejected 所以后面catch不會在處理了凶伙。

let p1 = new Promise((resolve,reject) => {
    setTimeout( () => resolve(200) , 1000)
})

p1.then(() => {
        console.log(11)
    })
    .then(() => {
        throw Error(22)
    })
    .then( () => {
        console.log(33)
    },fail => {
        console.log('this is from 3rd fn', fail)
    })
    .then( () => {
        console.log(44)
    })
    .catch(err => {
        console.log('this is error',err)
    })
    .then( () => {
        console.log(55)
    })
    
   
// 輸出為:
// 11
// this is from 3rd fn 22
// 44
// 55

怎么樣,有沒有想到它碎,處理錯誤之后函荣,還能繼續(xù)執(zhí)行显押,哪怕在catch后面也能執(zhí)行。

透過現(xiàn)象看本質(zhì)傻挂,下面我們對上面幾種情況用一個統(tǒng)一的解釋來理解下乘碑。

  • 首先我們要知道 then 方法,他接受兩個回調(diào)金拒,一個處理 fulilled狀態(tài)兽肤, 一個處理 rejected狀態(tài)。每次都返回一個新的promise 對象绪抛。

  • catch的本質(zhì)是obj.then(undefined, onRejected)资铡。

所以上面的幾種情況也就好理解了:

then 和 catch 都會返回一個promise 對象。當中間有狀態(tài)變?yōu)閞ejected之后幢码,他會一直往下尋找笤休,找到最近的rejected狀態(tài)處理函數(shù),之后根據(jù)處理函數(shù)的返回值繼續(xù)返回不同狀態(tài)的promise對象症副。一直執(zhí)行到鏈式調(diào)用的最后店雅。

所以我們在使用的時候要注意了,避免不必要的麻煩贞铣。一般用catch 來處理闹啦,并且放到最后。這樣能統(tǒng)一處理辕坝。

幾個常見題型

let p1 = new Promise((resolve, reject) => {
    console.log(11)
    resolve()
    console.log(22)
  })
  p1.then(() => {
    console.log(33)
  })
  console.log(44)

// 結果為:  11 窍奋、22 、44酱畅、33

解釋:Promise構造函數(shù)會立即執(zhí)行费变,所以先是11、resolve圣贸、22,由于then是異步的扛稽,所以代碼緊接著是44吁峻、最后才是33

Promise.resolve(11)
  .then(22)
  .then(Promise.resolve(33))
  .then(console.log)

// 輸出 11

解釋:then 參數(shù)不是function的時候都會被忽略。

使用場景

下面我們來看一下在张,它的一些常用場景:

1.異步b依賴異步a

// 異步請求b 依賴異步請求a
let p1 = new Promise(function(resolve,reject){
  $.post(urla,data,function(res){
    resolve(res);
  })
})

p1.then(function(res){
  $.post(urlb,data,function(){
    // 處理請求返回后的數(shù)據(jù)
  })
})

2.依賴異步a和異步b

我們有時候經(jīng)常會遇到這樣的一種場景用含,我們需要發(fā)起兩個互不依賴異步請求,然后等待兩個請求都返回之后再處理帮匾。

let p1 = new Promise((resolve,reject) =>{
    setTimeout( () => resolve(100), 200)
})

let p2 = new Promise((resolve,reject) =>{
    setTimeout( () => reject(200), 300)
})

Promise.all([p1,p2])
    .then(values =>{
        console.log(values);        // [100,200]
    },fail => {
        console.log(fail)
    })

all方法返回的是一個promise對象啄骇,所以他也有 then catch 等方法。

希望上面一點點內(nèi)容瘟斜,能夠幫助大家加深理解缸夹。如有錯誤痪寻,不吝指正。

作者:yjua
鏈接:https://juejin.im/post/5cf3c2915188255b0148df98

求點贊虽惭,求關注~


?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末橡类,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子芽唇,更是在濱河造成了極大的恐慌顾画,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匆笤,死亡現(xiàn)場離奇詭異研侣,居然都是意外死亡,警方通過查閱死者的電腦和手機炮捧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門庶诡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寓盗,你說我怎么就攤上這事灌砖。” “怎么了傀蚌?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵基显,是天一觀的道長。 經(jīng)常有香客問我善炫,道長撩幽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任箩艺,我火速辦了婚禮窜醉,結果婚禮上,老公的妹妹穿的比我還像新娘艺谆。我一直安慰自己榨惰,他們只是感情好,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布静汤。 她就那樣靜靜地躺著琅催,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虫给。 梳的紋絲不亂的頭發(fā)上藤抡,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機與錄音抹估,去河邊找鬼缠黍。 笑死,一個胖子當著我的面吹牛药蜻,可吹牛的內(nèi)容都是我干的瓷式。 我是一名探鬼主播替饿,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒿往!你這毒婦竟也來了盛垦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瓤漏,失蹤者是張志新(化名)和其女友劉穎腾夯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔬充,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡蝶俱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了饥漫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榨呆。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖庸队,靈堂內(nèi)的尸體忽然破棺而出积蜻,到底是詐尸還是另有隱情,我是刑警寧澤彻消,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布竿拆,位于F島的核電站,受9級特大地震影響宾尚,放射性物質(zhì)發(fā)生泄漏丙笋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一煌贴、第九天 我趴在偏房一處隱蔽的房頂上張望御板。 院中可真熱鬧,春花似錦牛郑、人聲如沸怠肋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灶似。三九已至,卻和暖如春瑞你,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背希痴。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工者甲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砌创。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓虏缸,卻偏偏與公主長得像鲫懒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子刽辙,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

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

  • Promise 對象 Promise 的含義 Promise 是異步編程的一種解決方案窥岩,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,708評論 1 56
  • 目錄:Promise 的含義基本用法Promise.prototype.then()Promise.prototy...
    BluesCurry閱讀 1,494評論 0 8
  • 一、Promise的含義 Promise在JavaScript語言中早有實現(xiàn)宰缤,ES6將其寫進了語言標準颂翼,統(tǒng)一了用法...
    Alex灌湯貓閱讀 827評論 0 2
  • 摘自:阮一峰 http://es6.ruanyifeng.com/#docs/promise 一、首先慨灭,我們要弄明...
    泡杯感冒靈閱讀 801評論 0 4
  • Promiese 簡單說就是一個容器朦乏,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果,語法上說氧骤,Pr...
    雨飛飛雨閱讀 3,361評論 0 19