JavaScript模擬實(shí)現(xiàn)Promise功能的示例代碼
模擬Promise的功能, 按照下面的步驟,一步一步
1. 新建是個(gè)構(gòu)造函數(shù)
2. 傳入一個(gè)可執(zhí)行函數(shù) 函數(shù)的入?yún)⒌谝粋€(gè)為 fullFill函數(shù) 第二個(gè)為 reject函數(shù); 函數(shù)立即執(zhí)行, 參數(shù)函數(shù)異步執(zhí)行
3. 狀態(tài)一旦更改就不可以變更 只能 pending => fulfilled 或者 pending => rejected
4. then 的時(shí)候要處理入?yún)⒌那闆r successCallback 和failCallback 均可能為非函數(shù)
默認(rèn)的 failCallback 一定要將異常拋出, 這樣下一個(gè)promise便可將其捕獲 異常冒泡的目的
5. then 中執(zhí)行回調(diào)的時(shí)候要捕獲異常 將其傳給下一個(gè)promise
- 如果promise狀態(tài)未變更 則將回調(diào)方法添加到對(duì)應(yīng)隊(duì)列中
- 如果promise狀態(tài)已經(jīng)變更 需要異步處理成功或者失敗回調(diào)
- 因?yàn)榭赡艹霈F(xiàn) 回調(diào)結(jié)果和當(dāng)前then返回的Promise一致 從而導(dǎo)致死循環(huán)問題
6. catch只是then的一種特殊的寫法 方便理解和使用
7. finally 特點(diǎn)
- 不過resolve或者reject都會(huì)執(zhí)行
- 回調(diào)沒有參數(shù)
- 返回一個(gè)Promise 且值可以穿透到下一個(gè)then或者catch
8. Promise.resolve, Promise.reject 根據(jù)其參數(shù)返回對(duì)應(yīng)的值 或者狀態(tài)的Promise即可
9. Proise.all 特點(diǎn)
- 返回一個(gè)Promise
- 入?yún)⑹菙?shù)組 resolve的情況下出參也是數(shù)組 且結(jié)果順序和調(diào)用順序一致
- 所有的值或者promise都完成才能resolve 所有要計(jì)數(shù)
- 只要有一個(gè)為reject 返回的Promise便reject
10. Proise.race 特點(diǎn)
- 返回一個(gè)Promise
- 入?yún)⑹菙?shù)組 那么出參根據(jù)第一個(gè)成功或者失敗的參數(shù)來確定
- 只要有一個(gè)resolve 或者reject 便更改返回Promise的狀態(tài)
const PENDING = 'pending' //等待
const FULFILLED = 'fulfilled' //成功
const REJECTED = 'rejected' //失敗
const fulfilledCallback = [] //成功回調(diào)函數(shù)
const rejectedCallback = [] //失敗回調(diào)函數(shù)
class MyPromise {
constructor (executor) {
try{
executor(this.resolve, this.reject)
} catch (e){
this.reject(e)
}
}
status = PENDING//promise的狀態(tài)
value = undefined//成功之后的值
reason = undefined//失敗之后的值
fulfilledCallback = [] //成功回調(diào)函數(shù)
rejectedCallback = [] //失敗回調(diào)函數(shù)
resolve = value => {
//如果狀態(tài)不是等待, 阻止程序繼續(xù)往下執(zhí)行
if(this.status !== PENDING){
return
}
this.status = FULFILLED
this.value = value
//判斷成功回調(diào)是否存在,如果存在, 調(diào)用
// this.fulfilledCallback && this.fulfilledCallback(this.value)
while(this.fulfilledCallback.length) this.fulfilledCallback.shift()()
}
reject = reason => {
//如果狀態(tài)不是等待, 阻止程序繼續(xù)往下執(zhí)行
if(this.status !== PENDING){
return
}
this.status = REJECTED
this.reason = reason
//判斷失敗回調(diào)是否存在,如果存在, 調(diào)用
// this.rejectedCallback && this.rejectedCallback(this.reason)
while(this.rejectedCallback.length) this.rejectedCallback.shift()()
}
then = (fulfilledCallback, rejectedCallback) => {
fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value
rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason}
let promise2 = new MyPromise((resolve, reject) => {
//判斷狀態(tài)
if(this.status === FULFILLED){
setTimeout(() => {
try {
//判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject,
//如果是普通值,直接調(diào)用resolve
let x = fulfilledCallback(this.value)
//外面加載完,才能獲取到promise2,用異步解決
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
}
},0)
}else if(this.status === REJECTED){
setTimeout(() => {
try {
//判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject,
//如果是普通值,直接調(diào)用resolve
let x = rejectedCallback(this.reason)
//外面加載完,才能獲取到promise2,用異步解決
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
}
},0)
}else{
//等待狀態(tài)
this.fulfilledCallback.push(() => {
setTimeout(() => {
try {
//判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject,
//如果是普通值,直接調(diào)用resolve
let x = fulfilledCallback(this.value)
//外面加載完,才能獲取到promise2,用異步解決
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
}
},0)
});
this.rejectedCallback.push(() => {
setTimeout(() => {
try {
//判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject,
//如果是普通值,直接調(diào)用resolve
let x = rejectedCallback(this.reason)
//外面加載完,才能獲取到promise2,用異步解決
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
}
},0)
});
}
})
return promise2
}
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 i = 0; i < array.length; i++) {
if (array[i] instanceof MyPromise) {
//promise對(duì)象
array[i].then(value => addData(i, value), reason => reject(reason))
} else {
//普通值, 放到數(shù)組里
addData(i, array[i])
}
}
})
}
static resolve (value) {
if(value instanceof MyPromise) return value
return new MyPromise(resolve => resolve(value))
}
finally (callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(() => {throw reason})
})
}
catch (rejectedCallback) {
return this.then(undefined, rejectedCallback)
}
}
function resolvePromise(promise2,x,resolve, reject){
if(x === promise2){
return reject(new TypeError('啦啦啦啦'))
}
if(x instanceof MyPromise){
//是promise
//往下直接傳
x.then(resolve,reject)
}else{
//普通值
resolve(x)
}
}
module.exports = MyPromise;到此這篇關(guān)于JavaScript模擬實(shí)現(xiàn)Promise功能的示例代碼的文章就介紹到這了,更多相關(guān)JavaScript實(shí)現(xiàn)Promise功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)的圖片3D展示空間(3DRoom)
一般的平面效果,通過改變水平和垂直坐標(biāo)就能實(shí)現(xiàn),再加上深度,就能在視覺上的產(chǎn)生3D(三維)的效果。2010-10-10
千萬不要錯(cuò)過的JavaScript高效對(duì)比數(shù)組差異方法
前端開發(fā)中,我們通常需要對(duì)比兩個(gè)數(shù)組對(duì)象的差異。這其中有很多種方法,但是有些方法會(huì)帶來一些問題,所以本文為大家準(zhǔn)備了一個(gè)高效方法,需要的可以參考一下2023-05-05
一文詳解Web Audio瀏覽器采集麥克風(fēng)音頻數(shù)據(jù)
這篇文章主要為大家介紹Web Audio瀏覽器采集麥克風(fēng)音頻數(shù)據(jù)實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Javascript的setTimeout()使用閉包特性時(shí)需要注意的問題
這篇文章主要介紹了Javascript的setTimeout(0)使用閉包特性時(shí)需要注意的問題,需要的朋友可以參考下2014-09-09
在JavaScript中獲取請(qǐng)求的URL參數(shù)[正則]
在ASP.NET后臺(tái)代碼中,對(duì)于這樣的URL請(qǐng)求地址:http://www.abc.com?id=001,我們可以通過Request.QueryString["id"]的方法很容易的獲取到URL中請(qǐng)求的參數(shù)的值,但是要在前臺(tái)js代碼中獲取請(qǐng)求的參數(shù)的值,應(yīng)該怎么做呢?2010-12-12
js經(jīng)驗(yàn)分享 JavaScript反調(diào)試技巧
在這篇文章中,我打算跟大家總結(jié)一下關(guān)于JavaScript反調(diào)試技巧方面的內(nèi)容。值得一提的是,其中有些方法已經(jīng)被網(wǎng)絡(luò)犯罪分子廣泛應(yīng)用到惡意軟件之中了,需要的朋友可以參考下2018-03-03
js實(shí)現(xiàn)同一個(gè)頁面多個(gè)漸變效果的方法
這篇文章主要介紹了js實(shí)現(xiàn)同一個(gè)頁面多個(gè)漸變效果的方法,涉及javascript操作漸變效果的實(shí)現(xiàn)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04

