一、Promise概述
Promise是一種用於處理異步操作的技術,它是一種異步計算的抽象,簡單來說就是實現異步編程的重要手段。Promise可以讓我們在代碼內部預先定義好異步操作成功後的結果值、失敗後的處理邏輯和如何響應異步操作結果的狀態。
以下是Promise的基本用法:
const promise = new Promise(function(resolve, reject) {
// 在這裡執行異步操作
// 成功時調用resolve,失敗時調用reject
});
promise.then(function(successResult) {
// 對於成功的處理邏輯
}).catch(function(errorResult) {
// 對於失敗的處理邏輯
});
首先我們創建了一個Promise實例,其中包含了resolve和reject兩個參數,在異步操作成功時調用resolve,並傳遞異步計算的結果給到then方法繼續處理。在異步操作拋出錯誤時,我們調用reject,並將錯誤信息傳給catch方法進行錯誤處理。
二、Promise狀態
Promise有3種狀態:
- pending – 未完成狀態,這時候既不是成功也不是失敗。
- fulfilled – 成功狀態,表示異步操作已經完成。
- rejected – 失敗狀態,表示異步操作已經失敗。
在Promise實例創建時,狀態為pending。當調用resolve時,狀態變為fulfilled;調用reject時,狀態變為rejected。Promise狀態一旦確定就不能再次改變。
以下是實現Promise狀態的例子:
let myPromise = new Promise((resolve, reject) => {
let isSuccess = true; // 異步操作是否成功
if (isSuccess) {
resolve("異步操作成功了!");
} else {
reject("異步操作失敗了!");
}
});
myPromise.then((result) => {
console.log(result);
}, (error) => {
console.log(error);
});
上述代碼中,當異步操作成功時,我們調用了resolve並傳遞了一個成功的結果給到then。在異步操作失敗時,我們調用了reject並傳遞了錯誤信息到catch方法。
三、 Promise API
1. Promise.all()
Promise.all接收一個Promise對象數組作為參數,當所有Promise對象完成時,它會返回一個由每個Promise結果值組成的數組。如果有任何一個Promise對象失敗,它 immediately 也會失敗,隨後的 then 方法不會執行,而是進入 catch。
以下是Promise.all的例子:
let promisesList = [Promise.resolve(3), Promise.resolve(4), new Promise((resolve, reject) => {
setTimeout(function () {
resolve('done');
}, 1000);
})];
Promise.all(promisesList).then(function (results) {
console.log(results);
}).catch(function (error) {
console.error(error);
});
當promisesList中所有的Promise對象完成時,則會打印值為3,4,和’done’的數組results。
2. Promise.race()
Promise.race接受一組Promise對象作為參數,並返回第一個完成後的Promise對象的結果,不管它是成功還是失敗。如果傳入一個空數組,Promise.race 將永遠處於等待狀態。
以下是Promise.race的例子:
let p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "p1");
});
let p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 200, "p2");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value);
// 在p2成功之後就立即完成
});
當p2成功時立即完成該Promise,返回值為’p2’。
3. Promise.reject()
Promise.reject是一個標準的Promise reject狀態函數,它返回一個帶有拒絕原因參數的Promise對象。
Promise.reject("Something went wrong").catch((reason) => {
console.log('Handle rejected promise ('+reason+') here.');
});
在使用Promise.reject時,我們將一個錯誤的消息傳遞給了catch方法,以便我們能夠及時處理Promise對象的拒絕狀態。
4. Promise.resolve()
Promise.resolve是一個標準的Promise resolved狀態函數,它返回一個解決的Promise對象。
Promise.resolve(4).then((result) => {
console.log(result + 5); // 輸出 9
});
在上述代碼中,我們將數字4傳遞給了Promise.resolve,當Promise對象解決時,輸出值為9。
四、Promise並行與串行
1. Promise並行
假設我們有多個異步任務需要同時進行,完成這些異步任務的最終結果是我們需要的。這時候可以使用Promise.all方法,根據Promise的規範,只有在所有Promise都同意完成後,Promise.all才會返回複合Promise中所有成功完成操作的結果的一個Promise。
以下是Promise並行的例子:
// 模擬異步任務
function task(num) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(num);
}, Math.random() * 3000);
});
}
// 多個異步任務同時進行
Promise.all([task(1), task(2), task(3)]).then(function(results) {
console.log(results); // [1,2,3]
}).catch(function(err) {
console.error(err);
});
在上述代碼中,我們使用Promise.all方法來實現多個異步任務的同時進行,當這些異步任務全部完成後,我們才會執行then方法,輸出每個任務的結果值。
2. Promise串行
當需要讓多個異步任務依次順序執行時,可以使用Promise.then方法。這種方式也稱為鏈式調用。
以下是Promise串行的例子:
// 模擬異步任務
function task(num) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(num);
}, Math.random() * 3000);
});
}
task(1)
.then(function(result) {
console.log(result);
return task(2);
})
.then(function(result) {
console.log(result);
return task(3);
})
.then(function(result) {
console.log(result);
})
.catch(function(err) {
console.error(err);
});
在上述代碼中,我們使用Promise.then方法來實現異步任務的順序執行,每一個任務都必須在上一個任務完成後才能執行。使用then方法將任務分別串聯起來,並輸出每一個結果值。
五、Promise優缺點
1. Promise優點
- 解決了回調地獄問題
- 更易於代碼維護和閱讀
- 提供了處理異步操作更好的方式
2. Promise缺點
- 無法取消Promise
- 在適用的情況下,速度比傳統回調慢,具有更多的內存消耗
- Promise 在處理硬盤異步IO(文件系統)時存在問題
六、結論
Promise是Javascript中異步編程的重要手段,通過引入Promise規範,我們可以更好地處理異步操作,避免回調地獄等問題;同時也提供了多種優化性能和提高可讀性的API。
不過Promise也有一些缺點,在使用過程中需要仔細斟酌,根據實際情況選擇是否使用。
原創文章,作者:JMYMW,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/332944.html