文章內(nèi)容輸出來源:拉勾教育大前端高薪訓(xùn)練營
文章說明:文章內(nèi)容為學(xué)習(xí)筆記吓坚,學(xué)徒之心,僅為分享; 如若有誤是牢,請?jiān)谠u論區(qū)指出僵井,如若您覺得文章內(nèi)容對您有一點(diǎn)點(diǎn)幫助,請點(diǎn)贊驳棱、關(guān)注批什、評論,共享
上一篇:JavaScript 深度剖析
簡單理解 Promise 的實(shí)現(xiàn)原理+自己手寫一個(gè) Promise
面試中社搅,經(jīng)常會(huì)被問到的問題:能否自己手動(dòng)寫一個(gè) Promise驻债,或者 Promise 內(nèi)部是如何實(shí)現(xiàn)異步調(diào)用的?
1形葬、你是否馬上想到合呐,完了不會(huì)啊 o(╥﹏╥)o,直接用笙以,還不一定用的明白呢淌实,內(nèi)部代碼如何實(shí)現(xiàn)的,鬼知道哇?
2猖腕、或者你也會(huì)想拆祈,管它內(nèi)部怎么實(shí)現(xiàn)的,拿來直接用不就完事了倘感,又不影響自己的代碼編程 →_→
可是面試官特別喜歡問這樣的問題放坏,你回答不上來,那么這次的面試基本也就沒有希望了【體現(xiàn)面試官很牛的樣子老玛,實(shí)際上面試官也不一定會(huì)淤年。。蜡豹∑侗矗】
但是下面的內(nèi)容恒傻,可以讓你成功實(shí)現(xiàn)一個(gè)自己手寫的 Promise鹰霍, 解決面試中的一問三不知的情況
進(jìn)入正題
要使用 Promise镜沽,首先要?jiǎng)?chuàng)建一個(gè) Promise 對象才行炊昆,
那么如何創(chuàng)建 Promise 對象桨吊?需要通過 new 關(guān)鍵字去執(zhí)行 Promise 就可以了
new Promise((resolve,reject)=>{})
1、由上面的代碼可以看出 Promise 是一個(gè)類凤巨,在執(zhí)行這個(gè)類的時(shí)候视乐,需要傳遞一個(gè)執(zhí)行器函數(shù)進(jìn)去,同時(shí)這個(gè)執(zhí)行器函數(shù)是立即執(zhí)行的
2敢茁、執(zhí)行器函數(shù)里面的 2 個(gè)參數(shù) resolve佑淀、reject 其實(shí)是 2 個(gè)函數(shù),這 2 個(gè)函數(shù)的目的就是去更改 Promise 的狀態(tài)
resolve:fulfilled 把狀態(tài)更改為成功
reject: rejected 把狀態(tài)更改為失敗
3彰檬、在 Promise 中的狀態(tài)有 3 種:
- pending 等待
- fulfilled 成功
- rejected 失敗
Promise 中的狀態(tài)只能是由等待狀態(tài) 變成 成功狀態(tài) 或者 由等待狀態(tài) 變成 失敗狀態(tài)
pending --> fulfilled
pending --> rejected
一旦狀態(tài)確定就不可更改
4伸刃、Promise 中的 then 方法內(nèi)部做的事情就是判斷 Promise 狀態(tài)谎砾,如果 Promise 狀態(tài)是成功,就調(diào)用 then()方法里面的成功的回調(diào)函數(shù)捧颅,也就是第一個(gè)函數(shù)景图,如果 Promise 狀態(tài)是失敗,就調(diào)用 then()方法里面的失敗的回調(diào)函數(shù)碉哑,也就是第二個(gè)函數(shù)挚币,then()方法石碑定義在原型對象中的
5、Promise 中的 then 方法內(nèi)成功的回調(diào)函數(shù)有一個(gè)參數(shù)扣典,表示成功之后的值妆毕,then 方法內(nèi)失敗的回調(diào)函數(shù)有一個(gè)參數(shù),表示失敗之后的值贮尖,
接下來按照上面的 5 點(diǎn)來創(chuàng)建最簡單的 Promise 原理的代碼
1笛粘、Promise 類核心邏輯實(shí)現(xiàn)
創(chuàng)建一個(gè) MyPromise.js 的文件,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve远舅,reject闰蛔,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值图柏,方便在then()方法中序六,拿到對應(yīng)的值
this.value = value
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值蚤吹,方便在then()方法中例诀,拿到對應(yīng)的值
this.reason = reason
}
then(sucessCallback, failCallback) {
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
sucessCallback(this.value)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)裁着,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
failCallback(this.reason)
}
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件繁涂,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件二驰,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
resolve('成功')
// reject('失敗')
})
p1.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
這樣最簡單的 Promise 就創(chuàng)建完成了
2扔罪、在 Promise 類中加入異步邏輯
創(chuàng)建一個(gè) MyPromise.js 的文件,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
value = undefined
reason = undefined
sucessCallback = undefined // then()方法里面的成功的回調(diào)
failCallback = undefined // then()方法里面的失敗的回調(diào)
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候桶雀,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = value
// 異步執(zhí)行矿酵,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
if (this.sucessCallback) {
this.sucessCallback(this.value)
}
}
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候矗积,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 異步執(zhí)行全肮,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
if (this.failCallback) {
this.failCallback(this.reason)
}
}
then(sucessCallback, failCallback) {
if (this.status === FULFILLED) {
sucessCallback
sucessCallback(this.value)
} else if (this.status === REJECTED) {
failCallback
failCallback(this.reason)
} else {
// 異步執(zhí)行棘捣,2秒后在執(zhí)行辜腺,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)閳?zhí)行器是同時(shí)執(zhí)行的,然后執(zhí)行器在執(zhí)行的時(shí)候,發(fā)現(xiàn)自身里面沒有找到promise的狀態(tài)评疗,
// 這時(shí)在執(zhí)行then()的時(shí)候测砂,then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)
// 所以then()方法里面打印出來的是空
// then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)的時(shí)候,
// 先把sucessCallback, failCallback,給保存起來
// 2秒后壤巷,就可以確認(rèn)調(diào)用resolve()還是reject()函數(shù)邑彪,
// 同時(shí)把值傳遞給then()方法里面的對應(yīng)的成功的回調(diào)或者失敗的回調(diào)
this.sucessCallback = sucessCallback
this.failCallback = failCallback
}
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件,文件內(nèi)導(dǎo)入 MyPromise.js 的文件胧华,同時(shí)使用該文件寄症,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行,2秒后在執(zhí)行矩动,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)閳?zhí)行器是同時(shí)執(zhí)行的有巧,然后執(zhí)行器在執(zhí)行的時(shí)候,發(fā)現(xiàn)自身里面沒有找到promise的狀態(tài)悲没,
// 這時(shí)在執(zhí)行then()的時(shí)候篮迎,then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)
// 所以then()方法里面打印出來的是空
// 然后去MyPromise.js文件中處理異步請求的情況
setTimeout(() => {
resolve('成功')
// reject('失敗')
}, 2000)
})
p1.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
3、在 Promise 類中實(shí)現(xiàn) then 方法的多次調(diào)用示姿,添加多個(gè)處理函數(shù)
創(chuàng)建一個(gè) MyPromise.js 的文件甜橱,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
value = undefined
reason = undefined
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = value
// 異步執(zhí)行栈戳,2秒后在執(zhí)行岂傲,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()(this.value)
}
}
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 異步執(zhí)行子檀,2秒后在執(zhí)行镊掖,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()(this.reason)
}
}
then(sucessCallback, failCallback) {
if (this.status === FULFILLED) {
sucessCallback
sucessCallback(this.value)
} else if (this.status === REJECTED) {
failCallback
failCallback(this.reason)
} else {
// 異步執(zhí)行,2秒后在執(zhí)行褂痰,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法亩进,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào),
// 用數(shù)組保存起來才可以
this.sucessCallback.push(sucessCallback)
this.failCallback.push(failCallback)
}
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件缩歪,文件內(nèi)導(dǎo)入 MyPromise.js 的文件归薛,同時(shí)使用該文件,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行匪蝙,2秒后在執(zhí)行主籍,來確定promise的狀態(tài)是成功還是失敗
setTimeout(() => {
resolve('異步執(zhí)行,成功')
// reject('異步執(zhí)行骗污,失敗')
}, 2000)
// resolve('成功')
// reject('失敗')
})
// then方法被調(diào)用了3次
p1.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
p1.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
p1.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
4、在 Promise 類中實(shí)現(xiàn) then 方法的鏈?zhǔn)秸{(diào)用一
創(chuàng)建一個(gè) MyPromise.js 的文件沈条,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
value = undefined
reason = undefined
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候需忿,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = value
// 異步執(zhí)行,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()(this.value)
}
}
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候屋厘,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 異步執(zhí)行涕烧,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()(this.reason)
}
}
then(sucessCallback, failCallback) {
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行汗洒,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
// 成功的回調(diào)议纯,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} else if (this.status === REJECTED) {
// 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
failCallback(this.reason)
} else {
// 異步執(zhí)行溢谤,2秒后在執(zhí)行瞻凤,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)世杀,
// 用數(shù)組保存起來才可以
this.sucessCallback.push(sucessCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件阀参,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件瞻坝,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行蛛壳,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// setTimeout(() => {
// resolve('異步執(zhí)行所刀,成功')
// // reject('異步執(zhí)行衙荐,失敗')
// }, 2000)
resolve('成功')
// reject('失敗')
})
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法浮创,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用忧吟,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
value => {
console.log(value)
return 100
},
reason => {
console.log(reason)
}
).then(
value => {
console.log(value) // 100
},
reason => {
console.log(reason)
}
)
5、在 Promise 類中實(shí)現(xiàn) then 方法的鏈?zhǔn)秸{(diào)用二
創(chuàng)建一個(gè) MyPromise.js 的文件蒸矛,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
value = undefined
reason = undefined
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候瀑罗,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = value
// 異步執(zhí)行,2秒后在執(zhí)行雏掠,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()(this.value)
}
}
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候斩祭,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行乡话,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()(this.reason)
}
}
then(sucessCallback, failCallback) {
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行摧玫,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象绑青,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} else if (this.status === REJECTED) {
// 失敗的回調(diào)诬像,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
failCallback(this.reason)
} else {
// 異步執(zhí)行,2秒后在執(zhí)行闸婴,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法坏挠,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào),
// 用數(shù)組保存起來才可以
this.sucessCallback.push(sucessCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(x, resolve2, reject2) {
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件邪乍,文件內(nèi)導(dǎo)入 MyPromise.js 的文件降狠,同時(shí)使用該文件对竣,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行,2秒后在執(zhí)行榜配,來確定promise的狀態(tài)是成功還是失敗
// setTimeout(() => {
// resolve('異步執(zhí)行否纬,成功')
// // reject('異步執(zhí)行,失敗')
// }, 2000)
resolve('成功')
// reject('失敗')
})
function other() {
return new MyPromise((resolve, reject) => {
return resolve('other')
})
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值蛋褥,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法临燃,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
value => {
console.log(value)
return other()
},
reason => {
console.log(reason)
// return other()
}
).then(
value => {
console.log(value) // other
},
reason => {
console.log(reason)
}
)
6烙心、then 方法鏈?zhǔn)秸{(diào)用識別 Promise 對象自返回
創(chuàng)建一個(gè) MyPromise.js 的文件膜廊,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
value = undefined
reason = undefined
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = value
// 異步執(zhí)行弃理,2秒后在執(zhí)行溃论,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()(this.value)
}
}
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 異步執(zhí)行痘昌,2秒后在執(zhí)行钥勋,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()(this.reason)
}
}
then(sucessCallback, failCallback) {
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
// 成功的回調(diào)辆苔,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象算灸,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} else if (this.status === REJECTED) {
// 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
failCallback(this.reason)
} else {
// 異步執(zhí)行驻啤,2秒后在執(zhí)行菲驴,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)骑冗,
// 用數(shù)組保存起來才可以
this.sucessCallback.push(sucessCallback)
this.failCallback.push(failCallback)
}
})
return promise2
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(x, resolve2, reject2) {
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件赊瞬,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件贼涩,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行巧涧,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// setTimeout(() => {
// resolve('異步執(zhí)行遥倦,成功')
// // reject('異步執(zhí)行谤绳,失敗')
// }, 2000)
resolve('成功')
// reject('失敗')
})
function other() {
return new MyPromise((resolve, reject) => {
return resolve('other')
})
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法袒哥,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用缩筛,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
value => {
console.log(value)
return other()
},
reason => {
console.log(reason)
// return other()
}
).then(
value => {
console.log(value) // other
},
reason => {
console.log(reason)
}
)
7、捕獲錯(cuò)誤及 then 鏈?zhǔn)秸{(diào)用其他狀態(tài)代碼補(bǔ)充
創(chuàng)建一個(gè) MyPromise.js 的文件堡称,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve瞎抛,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候却紧,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值桐臊,方便在then()方法中钞艇,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行,2秒后在執(zhí)行豪硅,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值挺物,方便在then()方法中懒浮,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行识藤,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行砚著,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象痴昧,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)稽穆,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象赶撰,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行舌镶,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法豪娜,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)餐胀,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象瘤载,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)否灾,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件鸣奔,文件內(nèi)導(dǎo)入 MyPromise.js 的文件墨技,同時(shí)使用該文件,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行挎狸,2秒后在執(zhí)行扣汪,來確定promise的狀態(tài)是成功還是失敗
setTimeout(() => {
resolve('異步執(zhí)行,成功')
// reject('異步執(zhí)行伟叛,失敗')
}, 2000)
// resolve('成功')
// throw new Error('執(zhí)行器錯(cuò)誤')
// reject('失敗')
})
function other() {
return new MyPromise((resolve, reject) => {
return resolve('other')
})
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值私痹,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法撤嫩,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用蹋订,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
value => {
console.log(value)
// throw new Error('第一個(gè)then拋出錯(cuò)誤')
},
reason => {
console.log(reason)
// return 10000
}
).then(
value => {
console.log(value)
},
reason => {
console.log(reason)
// return other()
}
)
8幽纷、將 then 方法的參數(shù)變成可選參數(shù)
創(chuàng)建一個(gè) MyPromise.js 的文件缘滥,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve敦第,reject摧茴,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候彰导,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值矢腻,方便在then()方法中鞭衩,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行学搜,2秒后在執(zhí)行娃善,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值瑞佩,方便在then()方法中聚磺,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行炬丸,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
// 主要代碼在這里
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行瘫寝,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象稠炬,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)焕阿,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象首启,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行暮屡,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法毅桃,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)褒纲,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象钥飞,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)外厂,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件代承,文件內(nèi)導(dǎo)入 MyPromise.js 的文件汁蝶,同時(shí)使用該文件,代碼如下:
const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
// 異步執(zhí)行论悴,2秒后在執(zhí)行掖棉,來確定promise的狀態(tài)是成功還是失敗
// resolve('成功')
reject('失敗')
})
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法膀估,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用幔亥,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then() // 等同于then((value)=>value)
.then() // 等同于then((value)=>value)
.then(
value => {
console.log(value)
},
reason => {
console.log(reason)
}
)
9、Promise.all([])方法的實(shí)現(xiàn)
創(chuàng)建一個(gè) MyPromise.js 的文件察纯,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve帕棉,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候饼记,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值香伴,方便在then()方法中,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行具则,2秒后在執(zhí)行即纲,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值博肋,方便在then()方法中低斋,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行蜂厅,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
// 主要代碼在這里
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行膊畴,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào)掘猿,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)唇跨,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào)术奖,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行轻绞,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法佣耐,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)政勃,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象兼砖,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)奸远,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
// 靜態(tài)方法讽挟,由類本身來調(diào)用
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let index = 0; index < array.length; index++) {
// 拿到當(dāng)前值
let current = array[index]
if (current instanceof MyPromise) {
// promise對象
current.then(
value => addData(index, value),
reason => reject(reason)
)
} else {
// 普通值
addData(index, array[index])
}
}
})
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件懒叛,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件耽梅,代碼如下:
const MyPromise = require('./MyPromise')
function p1() {
return new MyPromise((resolve, reject) => {
// 異步執(zhí)行薛窥,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
setTimeout(() => {
resolve('p1')
// reject('失敗')
}, 2000)
})
}
function p2() {
return new MyPromise((resolve, reject) => {
// 異步執(zhí)行眼姐,2秒后在執(zhí)行诅迷,來確定promise的狀態(tài)是成功還是失敗
resolve('p2')
// reject('失敗')
})
}
MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(
value => {
// value ==> ['a', 'b', 'p1', 'p2', 'c']
console.log(value)
},
error => {
console.log(error)
}
)
10、Promise.resolve 方法的實(shí)現(xiàn)
創(chuàng)建一個(gè) MyPromise.js 的文件众旗,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve罢杉,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候贡歧,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值滩租,方便在then()方法中,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行利朵,2秒后在執(zhí)行律想,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值绍弟,方便在then()方法中蜘欲,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行晌柬,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
// 主要代碼在這里
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行姥份,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào)郭脂,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)澈歉,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào)展鸡,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行埃难,2秒后在執(zhí)行莹弊,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)涡尘,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào)忍弛,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)考抄,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象细疚,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
// 靜態(tài)方法,由類本身來調(diào)用
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let index = 0; index < array.length; index++) {
// 拿到當(dāng)前值
let current = array[index]
if (current instanceof MyPromise) {
// promise對象
current.then(
value => addData(index, value),
reason => reject(reason)
)
} else {
// 普通值
addData(index, array[index])
}
}
})
}
// 靜態(tài)方法川梅,由類本身來調(diào)用
static resolve(value) {
// 傳入的值value是否為promise對象疯兼?
if (value instanceof MyPromise) {
// 傳入的值value是promise對象
return value
} else {
// 傳入的值,就是普通的值
return new MyPromise(resolve => resolve(value))
}
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件贫途,文件內(nèi)導(dǎo)入 MyPromise.js 的文件吧彪,同時(shí)使用該文件,代碼如下:
const MyPromise = require('./MyPromise')
function p1() {
return new MyPromise((resolve, reject) => {
// 異步執(zhí)行丢早,2秒后在執(zhí)行姨裸,來確定promise的狀態(tài)是成功還是失敗
resolve('p1')
// reject('失敗')
})
}
MyPromise.resolve(10).then(value => console.log(value))
MyPromise.resolve(p1()).then(value => console.log(value))
11、finally 方法的實(shí)現(xiàn)
創(chuàng)建一個(gè) MyPromise.js 的文件怨酝,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve啦扬,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候凫碌,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值扑毡,方便在then()方法中,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行盛险,2秒后在執(zhí)行瞄摊,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值苦掘,方便在then()方法中换帜,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行鹤啡,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
// 主要代碼在這里
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行惯驼,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)祟牲,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào)隙畜,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行说贝,2秒后在執(zhí)行议惰,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)乡恕,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào)言询,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)傲宜,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象运杭,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
// 靜態(tài)方法,由類本身來調(diào)用
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let index = 0; index < array.length; index++) {
// 拿到當(dāng)前值
let current = array[index]
if (current instanceof MyPromise) {
// promise對象
current.then(
value => addData(index, value),
reason => reject(reason)
)
} else {
// 普通值
addData(index, array[index])
}
}
})
}
// 靜態(tài)方法函卒,由類本身來調(diào)用
static resolve(value) {
// 傳入的值value是否為promise對象辆憔?
if (value instanceof MyPromise) {
// 傳入的值value是promise對象
return value
} else {
// 傳入的值,就是普通的值
return new MyPromise(resolve => resolve(value))
}
}
finally(callback) {
return this.then(
value => {
return MyPromise.resolve(callback()).then(() => value)
// callback()
// return value
},
reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
// callback()
// throw reason
}
)
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件谆趾,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件叛本,代碼如下:
const MyPromise = require('./MyPromise')
function p1() {
return new MyPromise((resolve, reject) => {
// 異步執(zhí)行沪蓬,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
setTimeout(() => {
resolve('p1成功')
// reject('p2失敗')
}, 2000)
})
}
function p2() {
return new MyPromise((resolve, reject) => {
resolve('p2成功')
// reject('失敗')
})
}
// finally()方法特點(diǎn):
// 1来候、無論promise對象的最終狀態(tài)是成功的跷叉,還是失敗的,finally方法中的回調(diào)函數(shù)始終會(huì)被執(zhí)行一次
// 2营搅、finally方法的后面可以使用鏈?zhǔn)秸{(diào)用then方法云挟,拿到當(dāng)前promise對象返回的結(jié)果
p2()
.finally(() => {
console.log('finally方法')
return p1()
})
.then(
value => console.log(value),
reason => console.log(reason)
)
12、catch 方法的實(shí)現(xiàn)
創(chuàng)建一個(gè) MyPromise.js 的文件转质,代碼如下:
const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗
class MyPromise {
// 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
constructor(executor) {
// 執(zhí)行器接收2個(gè)函數(shù)resolve园欣,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
// 一旦promise狀態(tài)確定就不可更改
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
// executor(this.resolve, this.reject)
}
status = PENDING // promise的狀態(tài)
value = undefined // 成功之后的值
reason = undefined // 失敗之后的值
sucessCallback = [] // then()方法里面的成功的回調(diào)
failCallback = [] // then()方法里面的失敗的回調(diào)
// 用箭頭函數(shù)的原因是為了解決this的指向問題
// resolve函數(shù)是用來更改promise的狀態(tài)的
resolve = value => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候休蟹,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為成功
this.status = FULFILLED
// 保存成功之后的值沸枯,方便在then()方法中,拿到對應(yīng)的值
this.value = value
// 異步執(zhí)行赂弓,2秒后在執(zhí)行绑榴,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.sucessCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.sucessCallback.shift()()
}
}
// resolve函數(shù)是用來更改promise的狀態(tài)的
reject = reason => {
// promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
if (this.status !== PENDING) return
// promise的狀態(tài)更改為失敗
this.status = REJECTED
// 保存成功之后的值盈魁,方便在then()方法中翔怎,拿到對應(yīng)的值
this.reason = reason
// 異步執(zhí)行,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
// 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
while (this.failCallback.length) {
// this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
// this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
// 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
this.failCallback.shift()()
}
}
then(sucessCallback, failCallback) {
// 主要代碼在這里
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise2 = new MyPromise((resolve2, reject2) => {
// MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
// 下面的代碼也必須立即執(zhí)行赤套,所以正好放在執(zhí)行器函數(shù)里面
// 判斷promise的狀態(tài)
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 成功的回調(diào)飘痛,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else if (this.status === REJECTED) {
// 失敗的回調(diào)于毙,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// failCallback(this.reason)
setTimeout(() => {
try {
// 失敗的回調(diào)敦冬,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
} else {
// 異步執(zhí)行唯沮,2秒后在執(zhí)行脖旱,來確定promise的狀態(tài)是成功還是失敗
// 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)介蛉,
// 用數(shù)組保存起來才可以
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
// sucessCallback()
setTimeout(() => {
try {
// 成功的回調(diào)萌庆,同時(shí)把成功的值傳遞給sucessCallback
// 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
this.failCallback.push(() => {
// failCallback()
setTimeout(() => {
try {
// 失敗的回調(diào)币旧,同時(shí)把失敗的值傳遞給failCallback
// 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
// 判斷X值是普通值還是promise對象
// 如果是普通值 直接調(diào)用resolve
// 如果是promise對象践险,查看promise對象返回的結(jié)果
// 再根據(jù)peomise對象返回的結(jié)果
// 決定調(diào)用resolve 還是調(diào)用reject
let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
resolvePromise(promise2, x, resolve2, reject2)
// resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
} catch (error) {
reject2(error)
}
}, 0)
})
}
})
return promise2
}
// 靜態(tài)方法,由類本身來調(diào)用
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let index = 0; index < array.length; index++) {
// 拿到當(dāng)前值
let current = array[index]
if (current instanceof MyPromise) {
// promise對象
current.then(
value => addData(index, value),
reason => reject(reason)
)
} else {
// 普通值
addData(index, array[index])
}
}
})
}
// 靜態(tài)方法吹菱,由類本身來調(diào)用
static resolve(value) {
// 傳入的值value是否為promise對象巍虫?
if (value instanceof MyPromise) {
// 傳入的值value是promise對象
return value
} else {
// 傳入的值,就是普通的值
return new MyPromise(resolve => resolve(value))
}
}
finally(callback) {
return this.then(
value => {
return MyPromise.resolve(callback()).then(() => value)
// callback()
// return value
},
reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
// callback()
// throw reason
}
)
}
catch(failCallback) {
return this.then(undefined, failCallback)
}
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
if (promise2 === x) {
return reject2(
new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (x instanceof MyPromise) {
// x 是promise對象
// x.then((value) => resolve2(value), (reason) => reject2(reason))
x.then(resolve2, reject2)
} else {
// x 是普通值
resolve2(x)
}
}
module.exports = MyPromise
創(chuàng)建一個(gè) index.js 文件鳍刷,文件內(nèi)導(dǎo)入 MyPromise.js 的文件占遥,同時(shí)使用該文件,代碼如下:
const MyPromise = require('./MyPromise')
function p1() {
return new MyPromise((resolve, reject) => {
resolve('p1成功')
reject('失敗')
})
}
p1()
.then(value => console.log(value))
.catch(reason => console.log(reason))
結(jié)語:
來拉鉤教育訓(xùn)練營學(xué)習(xí)已經(jīng)有二周了输瓜,在沒有來之前瓦胎,我都是回家之后打游戲(游戲名:斗戰(zhàn)神),來到這里之后才發(fā)現(xiàn)居然還有很多大佬也在學(xué)習(xí)尤揣,真的很驚訝搔啊,本人自身水平垃圾的一批,再不學(xué)習(xí)北戏,以后可能一直就是混吃等死的狀態(tài)了
- 首先來說负芋,拉鉤的課程很干,每個(gè)視頻很短嗜愈,都是干貨示罗,講師沒有一句廢話,視頻內(nèi)容覆蓋比較廣芝硬,布置的作業(yè)也比較符合實(shí)際蚜点,導(dǎo)師也會(huì)及時(shí)批改,然后一周或兩周必有直播拌阴,直播都會(huì)回答學(xué)習(xí)過程中所遇到的問題和新的內(nèi)容
- 其次來說绍绘,每個(gè)班都有班級群,群里居然還有5年或6年的前端開發(fā)的大佬(⊙▽⊙); 班主任和導(dǎo)師也在群里陪拘,有任何問題都可以在群里@導(dǎo)師厂镇,班級群真的很活躍
- 最后來說一句,如果有其他人也是在打游戲混日子左刽,不如來拉鉤教育訓(xùn)練營捺信,嘗試著改變一下自己目前所處的環(huán)境