目錄
實例方法
catch
finally
靜態方法
reslove
?reject
race?
all?
allSettled
any
實例方法
提供給promise實例的方法 包括catch 與finally
catch
Promise 實例的 catch() 方法用于注冊一個在 promise 被拒絕時調用的函數。它會立即返回一個等效的 Promise 對象,這可以允許你鏈式調用其他 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected) 的一種簡寫形式。
1 內部調用then方法(此方法是 Promise.prototype.then(undefined, onRejected) 的一種簡寫形式。)
2.處理異常 因為是實例化生成前拋出的異常 要 catch 捕獲實例化生成函數執行前
constructor(func) {const resolve = (result) => {if (this.state == PENDING) {this.state = FULFILLED;this.result = result;this.#handlers.forEach(({ onFulfilled }) => {onFulfilled(this.result);});}};const reject = (result) => {if (this.state == PENDING) {this.state = REJECTED;this.result = result;this.#handlers.forEach(({ onRejected }) => {onRejected(this.result);});}};try {func(resolve, reject);} catch (error) {reject(error);}}catch(onRejected) {return this.then(undefined, onRejected);}
// 測試代碼const p = new MyPromise((resolve, reject) => {reject("error");// throw "error";// return p2;// return 2;// return new MyPromise((resolve, reject) => {// resolve("OK");// // reject("ERROR");// });
});
p.then((res) => {console.log("res:", res);
}).catch((error) => {console.log("err:", err);
});
finally
Promise 實例的 finally() 方法用于注冊一個在 promise 敲定(兌現或拒絕)時調用的函數。它會立即返回一個等效的 Promise 對象,這可以允許你鏈式調用其他 promise 方法。
finally()?方法類似于調用?then(onFinally, onFinally)
這可以讓你避免在 promise 的 then() 和 catch() 處理器中重復編寫代碼。
onFinally
?回調函數不接收任何參數。這種情況恰好適用于你不關心拒絕原因或兌現值的情況,因此無需提供它。- 如果你想在 promise 敲定時進行一些處理或者清理,無論其結果如何,那么?
finally()
?方法會很有用。
finally(onFinally) {return this.then(onFinally, onFinally);}
const p = new MyPromise((resolve, reject) => {reject("error");// throw "error";
});
p.then((res) => {console.log("res:", res);
}).catch((error) => {console.log("err:", error);}).finally(() => {console.log("一定執行");});
靜態方法
提供給promise靜態的方法 包括以下6個
- reslove
- reject
- race
- all
- allsettled
- any
reslove
Promise.resolve() 靜態方法將給定的值轉換為一個 Promise。如果該值本身就是一個 Promise,那么該 Promise 將被返回;如果該值是一個 thenable 對象,Promise.resolve() 將調用其 then() 方法及其兩個回調函數;否則,返回的 Promise 將會以該值兌現
- 判斷傳入值
- promise直接返回
- 轉為promise并返回 ?fulfilled狀態
thenable對象指的是具有then方法的對象。Promise.resolve方法會將這個對象轉為Promise對象,然后立即執行thenable對象的then方法
/*** 靜態方法 resolve* 判斷傳入值* promise直接返回* 轉為promise并返回 fulfilled狀態*/static resolve(value) {if (value instanceof MyPromise) {return value;}return new MyPromise((resolve, reject) => {resolve(value);});}// 測試代碼// const p = MyPromise.resolve(
// new MyPromise((resolve, reject) => {
// resolve("ok");
// // reject("error");
// // throw "error";
// })
// );
const p = MyPromise.resolve("賈公子");
p.then((res) => {console.log("res:", res);},(error) => {console.log("err:", error);}
);
?reject
Promise.reject()
?靜態方法返回一個已拒絕(rejected)的?Promise
?對象,拒絕原因為給定的參數。?
static reject(value) {return new MyPromise((resolve, reject) => {reject(value);});}
// 測試代碼
const p = MyPromise.reject("賈公子");
p.then((res) => {console.log("res:", res);},(error) => {console.log("err:", error);}
);
race
?
Promise.race()
?靜態方法接受一個 promise 可迭代對象作為輸入,并返回一個?promise 這個返回的 promise 會隨著第一個 promise 的敲定而敲定。
接收一個promise數組 返回的結果以第一個和promise返回的結果為準
* 返回promise
* 判斷是否為數組(Array.isArray) 錯誤信息 ?Argument is not iterable
?* 等待第一個敲定 (forEach取出每一個promise執行 一旦執行就改變狀態resolve包裝一層 因為有可能傳遞的不是promise)
/*** 靜態方法 race* 返回promise* 判斷是否為數組 錯誤信息 Argument is not iterable* 等待第一個敲定*/static race(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.判斷是否為數組 錯誤信息 Argument is not iterableif (!Array.isArray(promises)) {return reject(new TypeError("Argument is not iterable"));}// 3.等待第一個敲定promises.forEach((p) => {MyPromise.resolve(p).then((res) => resolve(res),(err) => reject(err));});});}
}// 測試代碼const p1 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve("ok");}, 2000);
});
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {reject("err");}, 1000);
});
const p = MyPromise.race([p1, p2]);
// const p = MyPromise.race();
p.then((res) => {console.log("res:", res);},(error) => {console.log("err:", error);}
);
all
?
?Promise.all()
?靜態方法接受一個 Promise 可迭代對象作為輸入,并返回一個?Promise 。當所有輸入的 Promise 都被兌現時,返回的 Promise 也將被兌現(即使傳入的是一個空的可迭代對象),并返回一個包含所有兌現值的數組。如果輸入的任何 Promise 被拒絕,則返回的 Promise 將被拒絕,并帶有第一個被拒絕的原因。
- 1.返回promise
- 2.判斷是否為數組 錯誤信息 ?Argument is not iterable
- 3.空數組直接兌現
- 4.判斷全部兌現
- 4.1記錄結果(索引記錄保證兌現順序與傳入順序一樣)
- 4.2判斷 全部兌現 (不能使用length 因為使用索引添加的可能導致沒有全部兌現)
- 5.處理第一個拒絕
static all(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.判斷是否為數組 錯誤信息 Argument is not iterableif (!Array.isArray(promises)) {return reject(new TypeError("Argument is not iterable"));}// 3.空數組直接兌現promises.length === 0 && resolve(promises);// 4.判斷全部兌現const result = [];let count = 0;promises.forEach((p, index) => {MyPromise.resolve(p).then((res) => {// 4.1記錄結果(索引記錄保證兌現順序與傳入順序一樣)result[index] = res;// 4.2判斷 全部兌現 (不能使用length 因為使用索引添加的可能導致沒有全部兌現)count++;count === promises.length && resolve(result);},(err) => {// 5.處理第一個拒絕reject(err);});});});}// 測試代碼
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {// resolve("ok");reject("err");}, 1000);
});
const p3 = "賈公子";
const p = MyPromise.all([p1, p2, p3]);
// const p = MyPromise.all();、
// const p = MyPromise.all([]);p.then((res) => {console.log("res:", res);},(error) => {console.log("err:", error);}
);
allSettled
Promise.allSettled()
?靜態方法將一個 Promise 可迭代對象作為輸入,并返回一個單獨的?promise。當所有輸入的 Promise 都已敲定時(包括傳入空的可迭代對象時),返回的 Promise 將被兌現,并帶有描述每個 Promise 結果的對象數組。
??* 1.傳入的promise都已敲定,即可獲取兌現結果
?* ?2.結果數組: [{status: 'fulfilled', value: 1},{status: 'rejected', reason: 'err'}]
?* ?3.結果數組的順序,和傳入的promise數組的順序是一樣的
?* ?4.空數組直接兌現
?* ?5.不為數組 錯誤信息 ?Argument is not iterable
- 1.返回promise? 可以讓結果繼續.then
- ?2.數組判斷 不為數組直接拋出異常
- 3.為空直接敲定? 判斷length
- 4.等待全部敲定 使用forech 循環處理 利用resolve包裝一下
- 4.1記錄結果(result) 記錄敲定的次數(count) 不使用push 會導致沒有全部兌現
- 4.2 處理兌現{ status: FULFILLED, value: res }
- 4.3處理拒絕{ status: REJECTED, reason: err })
- 成功或者失敗都是resolve
static allSettled(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.數組判斷if (!Array.isArray(promises)) {return reject(new TypeError("Argument is not iterable"));}// 3.為空直接敲定promises.length === 0 && resolve(promises);// 4.等待全部敲定const result = [];let count = 0;promises.forEach((p, index) => {MyPromise.resolve(p).then((res) => {// 4.1記錄結果result[index] = { status: FULFILLED, value: res }; // 4.2 處理兌現{ status: FULFILLED, value: res }// 記錄敲定的次數count++;// 不論成功失敗都是resolvecount === promises.length && resolve(result);},(err) => {// 4.1記錄結果result[index] = { status: REJECTED, reason: err }; // 4.3處理拒絕{ status: REJECTED, reason: err }// 記錄敲定的次數count++;// 不論成功失敗都是resolvecount === promises.length && resolve(result);});});});}
// 測試代碼
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {// resolve("ok");reject("err");}, 1000);
});
const p3 = "賈公子";
const p = MyPromise.allSettled([p1, p2, p3]);
// const p = MyPromise.allSettled();
// const p = MyPromise.allSettled([]);p.then((res) => {console.log("res:", res);},(error) => {console.log("err:", error);}
);
any
Promise.any()
?靜態方法將一個 Promise 可迭代對象作為輸入,并返回一個?promise 當輸入的任何一個 Promise 兌現時,這個返回的 Promise 將會兌現,并返回第一個兌現的值。當所有輸入 Promise 都被拒絕(包括傳遞了空的可迭代對象)時,它會以一個包含拒絕原因數組的?AggregateErrorAggregateErrorAggregateError?拒絕。
AggregateError
?對象代表了包裝了多個錯誤對象的單個錯誤對象。當一個操作需要報告多個錯誤時,例如?promise.any,當傳遞給它的所有承諾都被拒絕時,就會拋出該錯誤。
?* 參數:promise數組
?* 結果
?* ? ?獲取到第一個成功的結果
?* ? ?獲取到所有拒絕失敗的原因 AggregateError: All promises were rejected[拒絕原因1,拒絕原因n]
?* ? ?傳入空數組,直接拒絕 AggregateError: All promises were rejected[]
?* ? ?不傳入數組直接報錯
?
- 1.返回promise?
- 2.數組判斷 錯誤信息 Argument is not iterable
- 3.空數組直接拒絕 AggregateError([錯誤原因],All promises were rejected[)
- 4.等待結果
- 4.1第一個兌現
- 4.2全部拒絕?
static any(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.數組判斷 錯誤信息 Argument is not iterableif (!Array.isArray(promises)) {return reject(new TypeError("Argument is not iterable"));}// 3.空數組直接拒絕 AggregateError([錯誤原因],All promises were rejected[)promises.length === 0 &&reject(new AggregateError(promises, "All promises were rejected"));const errors = [];let count = 0;// 4.等待結果promises.forEach((p, index) => {MyPromise.resolve(p).then((res) => {// 4.1第一個兌現resolve(res);},(err) => {// 4.2全部拒絕errors[index] = err;count++;count === promises.length &&reject(new AggregateError(errors, "All promises were rejected"));});});});}
// 測試代碼
const p1 = new MyPromise((resolve, reject) => {setTimeout(() => {// resolve("ok");reject("err1");}, 1000);
});
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {// resolve("ok");reject("err2");}, 2000);
});
// const p3 = "賈公子";
const p3 = MyPromise.reject("賈公子");const p = MyPromise.any([p1, p2, p3]);
// const p = MyPromise.any();
// const p = MyPromise.any([]);p.then((res) => {console.log("res:", res);},(error) => {// console.log("err:", error);console.dir(error);}
);