方案 網(wǎng)站建設(shè)快手seo軟件下載
筆記+分享
在現(xiàn)代JavaScript開發(fā)中,異步編程是不可避免的一部分。為了更好地處理異步操作,ES6引入了Promise。Promise使得異步代碼更具可讀性和可維護(hù)性。通過手寫一個完整的Promise實(shí)現(xiàn),可以幫助你更深入地理解其工作原理。本文將詳細(xì)介紹Promise的概念、用法及其在實(shí)際開發(fā)中的應(yīng)用,并提供一個手寫的Promise實(shí)現(xiàn)。
什么是Promise?
Promise是JavaScript中的一種對象,用于表示一個異步操作的最終完成(或失敗)及其結(jié)果值。它有三種狀態(tài):
- Pending(待定):初始狀態(tài),既沒有被兌現(xiàn),也沒有被拒絕。
- Fulfilled(已兌現(xiàn)):操作成功完成,并返回一個值。
- Rejected(已拒絕):操作失敗,并返回一個原因。
手寫Promise實(shí)現(xiàn)
我們將通過構(gòu)建一個簡化版的Promise實(shí)現(xiàn)來更好地理解其工作原理。
class MyPromise {constructor(executor) {this.state = 'pending'; // 初始狀態(tài)this.value = undefined; // 成功時的值this.reason = undefined; // 失敗時的原因this.onFulfilledCallbacks = []; // 成功的回調(diào)函數(shù)數(shù)組this.onRejectedCallbacks = []; // 失敗的回調(diào)函數(shù)數(shù)組const resolve = (value) => {if (this.state === 'pending') {this.state = 'fulfilled';this.value = value;this.onFulfilledCallbacks.forEach(fn => fn());}};const reject = (reason) => {if (this.state === 'pending') {this.state = 'rejected';this.reason = reason;this.onRejectedCallbacks.forEach(fn => fn());}};try {executor(resolve, reject);} catch (error) {reject(error);}}then(onFulfilled, onRejected) {onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };let promise2 = new MyPromise((resolve, reject) => {if (this.state === 'fulfilled') {setTimeout(() => {try {let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}}, 0);}if (this.state === 'rejected') {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}}, 0);}if (this.state === 'pending') {this.onFulfilledCallbacks.push(() => {setTimeout(() => {try {let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}}, 0);});this.onRejectedCallbacks.push(() => {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}}, 0);});}});return promise2;}catch(onRejected) {return this.then(null, onRejected);}static resolve(value) {return new MyPromise((resolve, reject) => {resolve(value);});}static reject(reason) {return new MyPromise((resolve, reject) => {reject(reason);});}static all(promises) {return new MyPromise((resolve, reject) => {let results = [];let completed = 0;const processResult = (index, value) => {results[index] = value;if (++completed === promises.length) {resolve(results);}};promises.forEach((promise, index) => {MyPromise.resolve(promise).then(value => {processResult(index, value);}, reject);});});}static race(promises) {return new MyPromise((resolve, reject) => {promises.forEach(promise => {MyPromise.resolve(promise).then(resolve, reject);});});}
}function resolvePromise(promise2, x, resolve, reject) {if (promise2 === x) {return reject(new TypeError('Chaining cycle detected for promise'));}let called = false;if (x && (typeof x === 'object' || typeof x === 'function')) {try {let then = x.then;if (typeof then === 'function') {then.call(x, y => {if (called) return;called = true;resolvePromise(promise2, y, resolve, reject);}, reason => {if (called) return;called = true;reject(reason);});} else {resolve(x);}} catch (error) {if (called) return;called = true;reject(error);}} else {resolve(x);}
}
關(guān)鍵點(diǎn)解釋
- 狀態(tài)管理:Promise有三種狀態(tài):
pending
、fulfilled
和rejected
。通過state
變量來管理當(dāng)前Promise的狀態(tài)。 - 回調(diào)隊(duì)列:使用兩個數(shù)組
onFulfilledCallbacks
和onRejectedCallbacks
來存儲在pending
狀態(tài)時注冊的回調(diào)函數(shù)。 - resolve和reject:
resolve
函數(shù)將Promise狀態(tài)從pending
變?yōu)?code>fulfilled,并執(zhí)行所有成功回調(diào);reject
函數(shù)將Promise狀態(tài)從pending
變?yōu)?code>rejected,并執(zhí)行所有失敗回調(diào)。 - then方法:
then
方法返回一個新的Promise,并根據(jù)當(dāng)前Promise的狀態(tài)決定如何處理回調(diào)函數(shù)。 - resolvePromise函數(shù):這個函數(shù)用來處理
then
方法中的鏈?zhǔn)秸{(diào)用,確保Promise的規(guī)范執(zhí)行,防止循環(huán)引用等問題。
用法示例
const p1 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('成功');}, 1000);
});p1.then(value => {console.log(value); // 輸出 "成功"return new MyPromise((resolve, reject) => {setTimeout(() => {resolve('鏈?zhǔn)秸{(diào)用成功');}, 1000);});
}).then(value => {console.log(value); // 輸出 "鏈?zhǔn)秸{(diào)用成功"
}).catch(error => {console.error(error);
});
通過這個手寫的Promise實(shí)現(xiàn),你可以更好地理解Promise的內(nèi)部工作機(jī)制,并在實(shí)際開發(fā)中靈活運(yùn)用Promise來處理異步操作。希望這篇博客能幫助你深入理解JavaScript中的Promise。