自定義的Promise

1琳拭、準(zhǔn)備知識


1训堆、回調(diào)函數(shù):

理解:一個函數(shù),自己定義的白嘁,自己沒有調(diào)用坑鱼,但是函數(shù)執(zhí)行了。

同步回調(diào):立即執(zhí)行絮缅,完全執(zhí)行完才結(jié)束姑躲,不會放到回調(diào)隊列中

?例子: 數(shù)組遍歷的forEach()還有promise的excutor

異步回調(diào):不會被立即執(zhí)行,會被放到回調(diào)函數(shù)中將來執(zhí)行

例子:定時器回調(diào)盟蚣、ajax回調(diào)黍析、promise的成功回調(diào)onResolve和失敗回調(diào)onReject

?2、錯誤類型

*Error:所有錯誤的父類型

ReferenceError:引用變量不存在屎开,打印一個未聲明的變量會觸發(fā)此錯誤

TypeError:數(shù)據(jù)類型不正確阐枣,將一個一般類型的變量當(dāng)成函數(shù)調(diào)用會觸發(fā)此錯誤

RangerError:數(shù)據(jù)值不在允許的方范圍,一個遞歸沒有跳出條件,遞歸會不斷執(zhí)行最后將棧占滿

SyntaxError:語法錯誤

*錯誤處理

捕獲錯誤:try...catch()? ?使代碼不會因為報錯而停止執(zhí)行

拋出錯誤:throw error 拋出的錯誤可以用try...catch()來接收

2奄抽、Promise

1蔼两、promise是什么:

promise是js中進(jìn)行異步編程的新的解決方案

具體表達(dá):

從語法上來說:promise是一個構(gòu)造函數(shù)

從功能上說:promise對象用來封裝一個異步操作并可以獲取其結(jié)果

2、promise狀態(tài):

pedding:初始狀態(tài)

resolve:成功狀態(tài)

reject:失敗狀態(tài)

3逞度、promise狀態(tài)的改變:

pending變?yōu)閞esolved

pending變?yōu)閞ejected

說明?:?只有這兩種额划,且一個promise對象只能改變一次

無論成功還是失敗,都只會由一個數(shù)據(jù)結(jié)果

成功的結(jié)果數(shù)據(jù)一般稱為value档泽,失敗的結(jié)果一般成為reason

4俊戳、promise包含的內(nèi)容:

promise構(gòu)造函數(shù):Promise(excutor{})

excutor函數(shù):同步執(zhí)行(resolve,reject)=>{}

resolve函數(shù):內(nèi)部定義成功時我們調(diào)用的函數(shù)?value=>{}

reject函數(shù):內(nèi)部定義失敗時我們調(diào)用的函數(shù)?reason=>{}

說明:excutor會在promise內(nèi)部立即同步回調(diào),異步操作在執(zhí)行器中執(zhí)行

4馆匿、promise的基本使用:

Promise是一個構(gòu)造函數(shù)抑胎,構(gòu)造函數(shù)的參數(shù)是一個函數(shù)即excutor(同步函數(shù)),該函數(shù)用來修改promise的狀態(tài)可以是pedding->resolve成功渐北,pedding->reject失敗阿逃。然后可以執(zhí)行.then()函數(shù)用來處理成功或者失敗的回調(diào)

5、promise的好處

1、指定回調(diào)函數(shù)的方式更加靈活:

舊的:必須在啟動異步任務(wù)前指定

?promise:?啟動異步任務(wù)==>返回promise對象=>給psomise對象綁定回調(diào)函數(shù)(甚至可以在異步任務(wù)執(zhí)行結(jié)束后指定)

2恃锉、支持鏈?zhǔn)秸{(diào)用?可以很好地解決回調(diào)地獄問題

什么是回調(diào)地獄:回調(diào)函數(shù)的嵌套調(diào)用搀菩,外部回調(diào)函數(shù)異步執(zhí)行的結(jié)果是嵌套回調(diào)函數(shù)執(zhí)行的條件

回調(diào)地獄的缺點(diǎn):不便于閱讀/不便于異步處理

6、Promise的基本方法

1破托、promise.prototype.then方法:(onResolved肪跋,onRejected)=>{}

onResolved函數(shù):成功的回調(diào)函數(shù)(value)=>{}

onRjected函數(shù):失敗的回調(diào)函數(shù)(reason)=>{}

說明:指定用于得到成功的value的成功回調(diào)和用于得到失敗的reason的失敗回調(diào)

返回一個新的promise對象

2、promise.prototype.catch方法:(onRejected)=>{}

onRejected函數(shù):失敗的回調(diào)函數(shù)(reason)=>{}

說明:相當(dāng)于then(undefined,onRejected)

3炼团、promise.resolve方法:(value)=>{}

value:成功的數(shù)據(jù)或promise對象

說明:返回一個成功/失敗的promise對象

?4、promise.reject方法:(reason)=>{}

?value:失敗的原因

?說明:返回失敗的promise對象

5疏尿、promise.all()方法:(promises)=>{}

promises:包含n個promise的數(shù)組

說明:返回一個新的promise瘟芝,只有所有的Prmise成功才成功,只要有一個失敗就直接失敗

6褥琐、promise.race()方法:(promises)=>{}

promises:包含n個promise的數(shù)組

說明:返回一個新的promise锌俱,第一個完成promise的結(jié)果狀態(tài)就是最終的結(jié)果

6、自定義promise之前的幾個關(guān)鍵問題

1敌呈、promise的狀態(tài)如何改變

resolve(value):如果當(dāng)前是pedding就會變成resolve

reject(reason):如果當(dāng)前是pedding那么就會變成reject

拋出異常:如果當(dāng)前是pedding就會變?yōu)閞eject

2贸宏、改變promise狀態(tài)和指定回調(diào)函數(shù)誰先誰后

(1)都有可能,正常情況下是先指定回調(diào)函數(shù)在改變狀態(tài),但是可以先改變狀態(tài)在指定回調(diào)

(2)如何先改變狀態(tài)在指定回調(diào)

? ? ?在執(zhí)行器中調(diào)用resolve()/reject()

? ? ? 延遲更長時間再調(diào)用then()

(3)什么時候才能得到數(shù)據(jù)

? ? ?如果先指定回調(diào)函數(shù),那么在狀態(tài)方法改變時磕洪,回調(diào)函數(shù)就會調(diào)用吭练,得到數(shù)據(jù)

? ? ? 如果先改變狀態(tài),那么當(dāng)指定回調(diào)時析显,回調(diào)函數(shù)就會調(diào)用鲫咽,得到數(shù)據(jù)

3、關(guān)于promise的then方法返回promise對象的狀態(tài)

promise.then()返回的新promise的結(jié)果狀態(tài)由什么決定谷异?

(1)簡單表達(dá):由then()指定的回調(diào)函數(shù)執(zhí)行的結(jié)果決定

(2)詳細(xì)表達(dá):

*如果拋出異常:新的promise變?yōu)閞ejected,reason為拋出的異常?

*如果返回的是一個非promise的任意值分尸,新promise變?yōu)閞esolved,value為返回的值歹嘹,如果沒有返回結(jié)果那么相當(dāng)于return undefined?

*如果返回的是另一個新的promise箩绍,此時promise的結(jié)果就會成為新的promise的結(jié)果

4、promise如何進(jìn)行串聯(lián)的多個任務(wù)操作

(1)promise的then()返回一個新的promise尺上,可以實(shí)現(xiàn)then的鏈?zhǔn)秸{(diào)用

(2)通過then的鏈?zhǔn)秸{(diào)用串聯(lián)多個同步/異步任務(wù)

5材蛛、promise異常穿透

(1)當(dāng)使用promise的then鏈?zhǔn)秸{(diào)用時,可以在最后面指定失敗的回調(diào)

(2)前面任何操作出了異常怎抛,都會傳到最后失敗的回調(diào)中去

中斷promise鏈

(1)當(dāng)使用promise的then鏈?zhǔn)秸{(diào)用時仰税,在中間中斷,不在調(diào)用后面的回調(diào)函數(shù)

(2)辦法:在回調(diào)函數(shù)中返回一個pendding狀態(tài)的promise對象

7抽诉、自定義的promise

1陨簇、promsie是一個構(gòu)造函數(shù)并且接受一個函數(shù)(excutor)作為參數(shù),這個函數(shù)是同步執(zhí)行的,該函數(shù)又接收兩個函數(shù)作為參數(shù)resolve(),reject()河绽。代碼實(shí)現(xiàn):

2己单、一個promise應(yīng)該有的數(shù)據(jù):狀態(tài)(pedding,resolve,reject),傳遞的數(shù)據(jù)耙饰,用于存儲then中的回調(diào)函數(shù)的數(shù)組纹笼。為什么要設(shè)置這個數(shù)組,因為我們前面討論過promise修改狀態(tài)和指定回調(diào)函數(shù)順序的問題(問題2)苟跪,如果先指定回調(diào)函數(shù)在修改狀態(tài)那么此時應(yīng)該將回調(diào)函數(shù)存儲起來廷痘,以便修改過狀態(tài)之后直接調(diào)用。代碼實(shí)現(xiàn):

3件已、resolve和reject函數(shù)所做的工作:修改狀態(tài)(只修改一次)笋额,將傳遞的數(shù)據(jù)保存,如果回調(diào)函數(shù)已經(jīng)指定那么執(zhí)行回調(diào)函數(shù)篷扩。代碼實(shí)現(xiàn):

4兄猩、如果promise拋出一個錯誤那么他將會執(zhí)行reject函數(shù),即問題1的第三點(diǎn)鉴未,代碼實(shí)現(xiàn):

5枢冤、then函數(shù)執(zhí)行以下幾種情況需要考慮:狀態(tài)是否已經(jīng)發(fā)生改變,如果改變直接執(zhí)行onResolved函數(shù)铜秆,如果沒有改變那么將onResolved函數(shù)和onRejected函數(shù)壓入callback數(shù)組中淹真,代碼實(shí)現(xiàn):

6、關(guān)于promise的then方法返回promise對象的狀態(tài)即問題3连茧,如果回調(diào)函數(shù)返回是promise趟咆,那么return的那個promise結(jié)果就是要向下傳遞的結(jié)果。這種情況在原裝的promise中是以return?new?promise.resolve(value)的形態(tài)呈現(xiàn)梅屉。

要想知道返回的是否成功必須取回promise的值值纱,因此用then的方法來獲取promise的值以及狀態(tài)

?如果成功說明原裝代碼為return?new?promise.resolve(value),返回的下一個狀態(tài)也應(yīng)該是成功坯汤,所以調(diào)用resolve

?如果失敗說明原裝代碼為return?new?promise.reject(reason)虐唠,返回的下一個狀態(tài)也應(yīng)該是失敗,所以調(diào)用reject

實(shí)現(xiàn)代碼:

7惰聂、如果then函數(shù)中不指定onResolved函數(shù)疆偿,onRejected函數(shù)時,promise有默認(rèn)的操作搓幌,如果是不指定onResolved函數(shù)杆故,那么把上面的value值繼續(xù)向下傳遞,如果不指定onRejected函數(shù)那么拋出一個錯誤溉愁。代碼實(shí)現(xiàn):

完整代碼:https://github.com/wangczc1234/Promise

最后歡迎大家投遞

字節(jié)跳動校招內(nèi)推碼: 2XVEJNC

校招投遞鏈接: https://jobs.toutiao.com/s/djchQRf

社招投遞鏈接: https://job.toutiao.com/s/djc2b4C

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末处铛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撤蟆,老刑警劉巖奕塑,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異家肯,居然都是意外死亡龄砰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門讨衣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來换棚,“玉大人,你說我怎么就攤上這事反镇」淘椋” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵愿险,是天一觀的道長颇蜡。 經(jīng)常有香客問我价说,道長辆亏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任鳖目,我火速辦了婚禮扮叨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘领迈。我一直安慰自己彻磁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布狸捅。 她就那樣靜靜地躺著衷蜓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尘喝。 梳的紋絲不亂的頭發(fā)上磁浇,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音朽褪,去河邊找鬼置吓。 笑死,一個胖子當(dāng)著我的面吹牛缔赠,可吹牛的內(nèi)容都是我干的衍锚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗤堰,長吁一口氣:“原來是場噩夢啊……” “哼戴质!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤置森,失蹤者是張志新(化名)和其女友劉穎斗埂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凫海,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呛凶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了行贪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漾稀。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖建瘫,靈堂內(nèi)的尸體忽然破棺而出崭捍,到底是詐尸還是另有隱情,我是刑警寧澤啰脚,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布殷蛇,位于F島的核電站,受9級特大地震影響橄浓,放射性物質(zhì)發(fā)生泄漏粒梦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一荸实、第九天 我趴在偏房一處隱蔽的房頂上張望匀们。 院中可真熱鬧,春花似錦准给、人聲如沸泄朴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祖灰。三九已至,卻和暖如春畔规,著一層夾襖步出監(jiān)牢的瞬間局扶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工油讯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留详民,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓陌兑,卻偏偏與公主長得像沈跨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子兔综,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354