国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【手寫promise——基本功能、鏈?zhǔn)秸{(diào)用、promise.all、promise.race】

這篇具有很好參考價值的文章主要介紹了【手寫promise——基本功能、鏈?zhǔn)秸{(diào)用、promise.all、promise.race】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。


前言

關(guān)于動機(jī),無論是在工作還是面試中,都會遇到Promise的相關(guān)使用和原理,手寫Promise也有助于學(xué)習(xí)設(shè)計模式以及代碼設(shè)計。
本文主要介紹了如何使用自己的代碼去實(shí)現(xiàn)Promise的一些功能。


以下是本篇文章正文內(nèi)容

一、前置知識

手寫之前,需要知道promise有哪些基本特性:

1、promise有三種狀態(tài):pending、fulfilled、rejected。

2、promise的默認(rèn)狀態(tài)是pending,狀態(tài)流轉(zhuǎn)有兩種:pending—>fulfilled、pending—>rejected。
【手寫promise——基本功能、鏈?zhǔn)秸{(diào)用、promise.all、promise.race】,javascript,前端,開發(fā)語言

3、實(shí)例化Promise時,可以接收一個函數(shù)作為參數(shù),這個函數(shù)有兩個參數(shù),分別是resolve、reject方法用于改變實(shí)例狀態(tài)。并能夠執(zhí)行下一個then中的回調(diào)函數(shù)。
4、then方法中接收兩個函數(shù)作為參數(shù),第一個函數(shù)相當(dāng)于執(zhí)行上一個 promise 中執(zhí)行 resolve 后對應(yīng)的回調(diào),第二個函數(shù)相當(dāng)于執(zhí)行上一個 promise 中執(zhí)行 reject 后對應(yīng)的回調(diào)。

// 1. 實(shí)例化 Promise 時
// 可以接收一個函數(shù)作為參數(shù),這個函數(shù)可以接收到 resolve 和 reject 兩個實(shí)例方法
// 用于更改當(dāng)前實(shí)例的狀態(tài),并把它們接收到的參數(shù)傳遞給下一個 then 對應(yīng)的參數(shù)中
  new Promise((resolve, reject) => {
    // resolve 和 reject 可以都執(zhí)行,但都執(zhí)行的意義不大,因?yàn)?promise 狀態(tài)發(fā)生更改后,就不能在被更改
    resolve('ok');
    // reject('err');
  }).then((value) => {
    console.log("resolve callback = ", value); // 若執(zhí)行 resolve,則 value = ok
  }, (reason) => {
    console.log("reject callback = ", reason); // 若執(zhí)行 reject,則 value = err
  });

5、then操作后會返回一個新的Promise,且支持鏈?zhǔn)秸{(diào)用。

let promise = new Promise((resolve,reject) => {
    resolve(11)
})
const a = new Promise((resolve,reject) => {
    reject('ok')
})
promise.then(res => {
    console.log(res)
    return a
}).then(res => console.log(res))

6、Promise.all以數(shù)組的形式接收多個Promise,當(dāng)所有Promise執(zhí)行完成,且狀態(tài)都為fulfilled時,返回執(zhí)行成功的結(jié)果;有一個失敗,則返回失敗的結(jié)果。

7、Promise.race以數(shù)組的形式接收多個Promise,只要有一個Promise先執(zhí)行成功,無論什么狀態(tài),都返回這個結(jié)果,給到下一個then中對應(yīng)的回調(diào)。

二、實(shí)現(xiàn)基本功能

1、

  • new 操作
  • resolve、reject方法
  • then方法
// 定義三種狀態(tài)
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
    constructor(executor) {

         // 1、默認(rèn)狀態(tài) - PENDING
         this.status = PENDING;
         // 2、內(nèi)部維護(hù)的變量值
         this.value = undefined;
         this.reason = undefined;

        try {
            executor(this.resolve.bind(this), this.reject.bind(this)) // 實(shí)例化傳進(jìn)來的函數(shù)會立即執(zhí)行
        } catch(err) {
            this.reject(err)
        }
    }
    resolve(value) {
        if (this.status === PENDING) {
            this.value = value;
            this.status = FULFILLED;
        }
    }
    reject(reason) {
        if (this.status === PENDING) {
            this.reason = reason;
            this.status = REJECTED;
        }
    }
    then(onFulfilled, onRejected) {
        if (onFulfilled && this.status === FULFILLED) {
            let res = onFulfilled(this.value)
            this.resolvePromise(res, resolve, reject)
        }
        if (onRejected && this.status === REJECTED) {
            let res = onRejected(this.reason)
            this.resolvePromise(res, resolve, reject)
        }        
    }
}

通過以下代碼自測:

new Promise((resolve,reject) => {
    resolve(1)
}).then(res=> {
	console.log(res) // 1
})

2、考慮異步的情況。
以上代碼都是同步的,Promise實(shí)例化時傳入了異步函數(shù)如setTimeout,在setTimeout中resolve,在下一個then的回調(diào)函數(shù)獲取異步函數(shù)的狀態(tài)呢?

我們可以使用回調(diào)隊(duì)列緩存起來,等待執(zhí)行:

// 定義三種狀態(tài)
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
    constructor(executor) {

         // 1、默認(rèn)狀態(tài) - PENDING
         this.status = PENDING;
         // 2、內(nèi)部維護(hù)的變量值
         this.value = undefined;
         this.reason = undefined;
         this.onResolveCallBack = [];// 緩存 onResolve 
    	 this.onRejectCallBack = [];// 緩存 onReject 

        try {
            executor(this.resolve.bind(this), this.reject.bind(this)) // 實(shí)例化傳進(jìn)來的函數(shù)會立即執(zhí)行
        } catch(err) {
            this.reject(err)
        }
    }
    resolve(value) {
        if (this.status === PENDING) {
            this.value = value;
            this.status = FULFILLED;
            // 遍歷調(diào)用 onResolveCallBack
      		this.onResolveCallBack.forEach(fn => fn());
        }
    }
    reject(reason) {
        if (this.status === PENDING) {
            this.reason = reason;
            this.status = REJECTED;
            this.onResolveCallBack.forEach(fn => fn());
        }
    }
    then(onFulfilled, onRejected) {
        if (onFulfilled && this.status === FULFILLED) {
            let res = onFulfilled(this.value)
            this.resolvePromise(res, resolve, reject)
        }
        if (onRejected && this.status === REJECTED) {
            let res = onRejected(this.reason)
            this.resolvePromise(res, resolve, reject)
        }
        // 當(dāng)前 promise 狀態(tài)為 pending,把當(dāng)前的 onResolve & onReject 緩存起來
        if (this.status === PENDING) {
        	this.onResolveCallBack.push(() => {
        		onResolve(this.value);
        	});	
		    this.onRejectCallBack.push(() => {
		      onReject(this.value);
		    });
  		}       
    }
}

用以下代碼測試通過:

 let p = new MyPromise((resolve, reject) => {
      setTimeout(()=>{
        resolve(1);
      },1000);
    }).then(value => {
      console.log('then resolve = ', value);
    }, reason => {
      console.log('then reject = ', reason);
    });
// then resolve = 1

二、實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

then(onFulfilled, onRejected) {
   	return new Promise((resolve, reject) => { // 支持鏈?zhǔn)秸{(diào)用
         if (onFulfilled && this.status === FULFILLED) {
             let res = onFulfilled(this.value)
             resolve(res);
         }
         if (onRejected && this.status === REJECTED) {
             let res = onRejected(this.reason)
             resolve(res);
         }
         if (this.status === PENDING) {
             this.onResolvedCallbacks.push(() =>{
                 let res = onFulfilled(this.value)
                 resolve(res);
             })
             this.onRejectedCallbacks.push(() => {
                 let res = onRejected(this.reason)
                 resolve(res);
             })
         }
     })   
 }

測試用例:

let promise = new Promise((resolve,reject) => {
    resolve(1)
})
promise.then(res => {
    return 2 // 返回普通對象
}).then(res => console.log(res)) // 2

如果在then中返回的是普通對象,上述代碼能滿足,如果返回的是一個Promise,則還需要補(bǔ)充:

then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => { // 支持鏈?zhǔn)秸{(diào)用
         if (onFulfilled && this.status === FULFILLED) {
             let res = onFulfilled(this.value)
             this.resolvePromise(res, resolve, reject)
         }
         if (onRejected && this.status === REJECTED) {
             let res = onRejected(this.reason)
             this.resolvePromise(res, resolve, reject)
         }
         if (this.status === PENDING) {
             this.onResolvedCallbacks.push(() =>{
                 let res = onFulfilled(this.value)
                 this.resolvePromise(res, resolve, reject)
             })
             this.onRejectedCallbacks.push(() => {
                 let res = onRejected(this.reason)
                 this.resolvePromise(res, resolve, reject)
             })
         }
     })
     
 }
 resolvePromise(res, resolve, reject) {
     if(res instanceof Promise) { // 對then中返回Promise做處理
         res.then(resolve, reject)
       } else{
         // 普通值
         resolve(res)
     }
 }

測試用例:

let promise = new Promise((resolve,reject) => {
    resolve(11)
})
const a = new Promise((resolve,reject) => {
    reject('ok')
})
promise.then(res => {
   return a;
}).then(res => console.log(res)) // ok

三、實(shí)現(xiàn)Promise.all

由上述前置知識可知,Promise.all是全部成功才返回成功的結(jié)果,有一個失敗就返回失敗的結(jié)果:

Promise.all = function(arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) {
            return reject("參數(shù)必須為數(shù)組");
        }
        let successNum = 0; // 成功的Promise條數(shù)
        let resultArray = [];
        let totalNum = arr.length; // 總Promise數(shù)量
        let isFail = false;
        arr.forEach(item => {
            item.then(res => {
                successNum++;
                resultArray.push(res);
                if (successNum === totalNum) { // 說明是全部成功
                    return resolve(resultArray)
                }
            }, err => {
               if (!isFail) reject(err)
               isFail = true;
            })
        });       
    })
}

測試用例:

function wait500(input) {
	return new Promise((resolve, reject) => {
		setTimeout(()=> {
			resolve(500)
		}, 500)
	})
}
function wait1000(input) {
	return new Promise((resolve, reject) => {
		setTimeout(()=> {
			resolve(1000)
		}, 1000)
	})
}
// 全部執(zhí)行完成之后回調(diào)
Promise.all([wait1000(), wait500()]).then(result => {
	console.log('all end', result)
}, err => {
    console.log('fafaf', err)
}) // 'all end [500, 1000]'

四、實(shí)現(xiàn)Promise.race

由上述前置知識可知,Promise.race是有一個promise先執(zhí)行成功,無論什么狀態(tài),都返回這個結(jié)果:

Promise.race = function(arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) {
            return reject("參數(shù)必須為數(shù)組");
        }
        arr.forEach(item => {
            item.then(res => {
                return resolve(res); // 狀態(tài)不可逆,只要其中一個Promise轉(zhuǎn)變了狀態(tài),后續(xù)狀態(tài)就不會發(fā)生改變
            }, err => {
                reject(err);
            })
        });       
    })

}

測試用例:

function wait500(input) {
	return new Promise((resolve, reject) => {
		setTimeout(()=> {
			resolve(500)
		}, 500)
	})
}
function wait1000(input) {
	return new Promise((resolve, reject) => {
		setTimeout(()=> {
			resolve(1000)
		}, 1000)
	})
}
Promise.race([wait1000(), wait500()]).then(result => {
	console.log('all end', result)
}, err => {
    console.log('fafaf', err)
}) // 打印出'all end 500'

總結(jié)

總的代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-681995.html

const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
    constructor(executor) {

         // 1、默認(rèn)狀態(tài) - PENDING
         this.status = PENDING;
         // 2、內(nèi)部維護(hù)的變量值
         this.value = undefined;
         this.reason = undefined;

         // 存放回調(diào)
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];
        try {
            executor(this.resolve.bind(this), this.reject.bind(this))
        } catch(err) {
            this.reject(err)
        }
    }
    resolve(value) {
        if (this.status === PENDING) {
            this.value = value;
            this.status = FULFILLED;
            this.onResolvedCallbacks.forEach(fn => fn())
        }

    }
    reject(reason) {
        if (this.status === PENDING) {
            this.reason = reason;
            this.status = REJECTED;
            this.onRejectedCallbacks.forEach(fn => fn())
        }
    }
    then(onFulfilled, onRejected) {
        return new Promise((resolve, reject) => { // 支持鏈?zhǔn)秸{(diào)用
            if (onFulfilled && this.status === FULFILLED) {
                let res = onFulfilled(this.value)
                this.resolvePromise(res, resolve, reject)
            }
            if (onRejected && this.status === REJECTED) {
                let res = onRejected(this.reason)
                this.resolvePromise(res, resolve, reject)
            }
            if (this.status === PENDING) {
                this.onResolvedCallbacks.push(() =>{
                    let res = onFulfilled(this.value)
                    this.resolvePromise(res, resolve, reject)
                })
                this.onRejectedCallbacks.push(() => {
                    let res = onRejected(this.reason)
                    this.resolvePromise(res, resolve, reject)
                })
            }
        })
        
    }
    resolvePromise(res, resolve, reject) {
        if(res instanceof Promise) {
            res.then(resolve, reject)
          } else{
            // 普通值
            resolve(res)
        }
    }
}
// 全部成功才返回成功的結(jié)果,有一個失敗就返回失敗的結(jié)果
Promise.all = function(arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) {
            return reject("參數(shù)必須為數(shù)組");
        }
        let successNum = 0;
        let resultArray = [];
        let totalNum = arr.length;
        let isFail = false;
        arr.forEach(item => {
            item.then(res => {
                successNum++;
                resultArray.push(res);
                if (successNum === totalNum) {
                    return resolve(resultArray)
                }
            }, err => {
                if (!isFail) reject(err)
                isFail = true;
            })
        });       
    })
}

// 某個promise先完成,
Promise.race = function(arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) {
            return reject("參數(shù)必須為數(shù)組");
        }
        arr.forEach(item => {
            item.then(res => {
                return resolve(res);
            }, err => {
                reject(err);
            })
        });       
    })

}

到了這里,關(guān)于【手寫promise——基本功能、鏈?zhǔn)秸{(diào)用、promise.all、promise.race】的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • promise的鏈?zhǔn)秸{(diào)用和promise的嵌套的實(shí)現(xiàn)

    話不多說 直接看下面 Promise的鏈?zhǔn)秸{(diào)用(Chaining)和Promise的嵌套(Nesting)是常見的Promise使用場景,下面我將為您展示它們的實(shí)現(xiàn)方法。 鏈?zhǔn)秸{(diào)用 在鏈?zhǔn)秸{(diào)用中,我們可以通過多次調(diào)用then方法來串聯(lián)執(zhí)行多個異步操作。每個then方法都返回一個新的Promise對象,使得我們可以在

    2024年02月15日
    瀏覽(24)
  • 【JavaScript】手寫Promise

    【JavaScript】手寫Promise

    ?? 個人主頁: 不叫貓先生 ???♂? 作者簡介:2022年度博客之星前端領(lǐng)域TOP 2,前端領(lǐng)域優(yōu)質(zhì)作者、阿里云專家博主,專注于前端各領(lǐng)域技術(shù),共同學(xué)習(xí)共同進(jìn)步,一起加油呀! ??優(yōu)質(zhì)專欄:vue3從入門到精通、TypeScript從入門到實(shí)踐 ?? 資料領(lǐng)?。呵岸诉M(jìn)階資料可以找我免

    2024年02月05日
    瀏覽(21)
  • 手寫Promise的基本實(shí)現(xiàn) (超詳細(xì))

    目錄 一:首先分析官方的promise 二:手寫Promise-then方法設(shè)計 三:then方法優(yōu)化: 四:Promise-catch方法設(shè)計 ?五:Promise-finally方法設(shè)計 //本文帶大家實(shí)現(xiàn)一個基本的 promise 過多的邊界情況就不在考虐,理解主要實(shí)現(xiàn)過程以及邏輯即可 //對于一個個出現(xiàn)的問題?我會逐步分析原因以及

    2024年02月16日
    瀏覽(21)
  • 如何在JavaScript中實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用(chaining)?

    如何在JavaScript中實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用(chaining)?

    前端入門之旅:探索Web開發(fā)的奇妙世界 記得點(diǎn)擊上方或者右側(cè)鏈接訂閱本專欄哦 幾何帶你啟航前端之旅 歡迎來到前端入門之旅!這個專欄是為那些對Web開發(fā)感興趣、剛剛踏入前端領(lǐng)域的朋友們量身打造的。無論你是完全的新手還是有一些基礎(chǔ)的開發(fā)者,這里都將為你提供一

    2024年02月08日
    瀏覽(23)
  • 【ES6】Promise.race的用法

    【ES6】Promise.race的用法

    Promise.race()方法同樣是將多個 Promise 實(shí)例,包裝成一個新的 Promise 實(shí)例。 上面代碼中,只要p1、p2、p3之中有一個實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變。那個率先改變的 Promise 實(shí)例的返回值,就傳遞給p的回調(diào)函數(shù)。 Promise.race()方法的參數(shù)與Promise.all()方法一樣,如果不是 Pr

    2024年02月10日
    瀏覽(20)
  • promise學(xué)習(xí)1-promise特點(diǎn),手寫簡易版promise

    1.promise有三個狀態(tài) 成功態(tài)(resolve) 失敗態(tài)(reject) 等待態(tài)(pending)(既不成功也不失?。?舉個例子,女友叫你給她買包 買 不買 不說話 promise就是一個類,所以要new。promise默認(rèn)為pending狀態(tài)。 2.用戶自己決定成功和失敗的原因,也決定最后是否成功還是失敗 3.promise默認(rèn)執(zhí)

    2024年02月15日
    瀏覽(18)
  • async/await實(shí)現(xiàn)Promise.all()

    ??個人主頁: 不叫貓先生 ???♂?作者簡介:專注于前端領(lǐng)域各種技術(shù),熱衷分享,期待你的關(guān)注。 ??系列專欄:vue3從入門到精通 ??個人簽名:不破不立 Promise.all() 方法接收一個 promise 的 iterable 類型(注:Array,Map,Set 都屬于 ES6 的 iterable 類型)的輸入,并且 只返回

    2024年01月18日
    瀏覽(45)
  • 【ES6】Promise.all用法

    【ES6】Promise.all用法

    Promise.all()方法用于將多個 Promise 實(shí)例,包裝成一個新的 Promise 實(shí)例。 上面代碼中,Promise.all()方法接受一個數(shù)組作為參數(shù),p1、p2、p3都是 Promise 實(shí)例,如果不是,就會先調(diào)用下面講到的Promise.resolve方法,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例,再進(jìn)一步處理。另外,Promise.all()方法的參數(shù)可以

    2024年02月09日
    瀏覽(18)
  • Vue:使用Promise.all()方法并行執(zhí)行多個請求

    在Vue中,可以使用Promise.all()方法來并行執(zhí)行多個請求。當(dāng)需要同時執(zhí)行多個異步請求時,可以將這些請求封裝為Promise對象并使用Promise.all()方法來執(zhí)行它們。 示例1: 以下是一個示例代碼,展示了如何通過Promise.all()方法并行執(zhí)行多個請求: 在上述示例中,定義了三個請求:

    2024年02月12日
    瀏覽(32)
  • 微信小程序-多圖片上傳(基于Promise.all實(shí)現(xiàn))

    微信小程序-多圖片上傳(基于Promise.all實(shí)現(xiàn))

    如你所了解到的,微信小程序的wx.uploadFile每次僅支持單文件上傳。但在實(shí)際的應(yīng)用場景中往往有多文件上傳的需求。因此我打算用Promise.all對wx.uploadFile進(jìn)行一層封裝,讓其能夠?qū)崿F(xiàn)多文件上傳。 說在前面:若你了解Promise.all的用法.那么你一定知道這樣封裝的結(jié)果: 同時上傳多

    2023年04月09日
    瀏覽(89)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包