方案 網站建設快手seo軟件下載
筆記+分享
在現(xiàn)代JavaScript開發(fā)中,異步編程是不可避免的一部分。為了更好地處理異步操作,ES6引入了Promise。Promise使得異步代碼更具可讀性和可維護性。通過手寫一個完整的Promise實現(xiàn),可以幫助你更深入地理解其工作原理。本文將詳細介紹Promise的概念、用法及其在實際開發(fā)中的應用,并提供一個手寫的Promise實現(xiàn)。
什么是Promise?
Promise是JavaScript中的一種對象,用于表示一個異步操作的最終完成(或失敗)及其結果值。它有三種狀態(tài):
- Pending(待定):初始狀態(tài),既沒有被兌現(xiàn),也沒有被拒絕。
- Fulfilled(已兌現(xiàn)):操作成功完成,并返回一個值。
- Rejected(已拒絕):操作失敗,并返回一個原因。
手寫Promise實現(xiàn)
我們將通過構建一個簡化版的Promise實現(xiàn)來更好地理解其工作原理。
class MyPromise {constructor(executor) {this.state = 'pending'; // 初始狀態(tài)this.value = undefined; // 成功時的值this.reason = undefined; // 失敗時的原因this.onFulfilledCallbacks = []; // 成功的回調函數(shù)數(shù)組this.onRejectedCallbacks = []; // 失敗的回調函數(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);}
}
關鍵點解釋
- 狀態(tài)管理:Promise有三種狀態(tài):
pending
、fulfilled
和rejected
。通過state
變量來管理當前Promise的狀態(tài)。 - 回調隊列:使用兩個數(shù)組
onFulfilledCallbacks
和onRejectedCallbacks
來存儲在pending
狀態(tài)時注冊的回調函數(shù)。 - resolve和reject:
resolve
函數(shù)將Promise狀態(tài)從pending
變?yōu)?code>fulfilled,并執(zhí)行所有成功回調;reject
函數(shù)將Promise狀態(tài)從pending
變?yōu)?code>rejected,并執(zhí)行所有失敗回調。 - then方法:
then
方法返回一個新的Promise,并根據(jù)當前Promise的狀態(tài)決定如何處理回調函數(shù)。 - resolvePromise函數(shù):這個函數(shù)用來處理
then
方法中的鏈式調用,確保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('鏈式調用成功');}, 1000);});
}).then(value => {console.log(value); // 輸出 "鏈式調用成功"
}).catch(error => {console.error(error);
});
通過這個手寫的Promise實現(xiàn),你可以更好地理解Promise的內部工作機制,并在實際開發(fā)中靈活運用Promise來處理異步操作。希望這篇博客能幫助你深入理解JavaScript中的Promise。