一、Promise簡介
Promise是JS中非常重要的概念,它可以用來封裝異步操作,讓代碼更加優雅易讀。
Promise是一種設計模式,用於優雅地處理異步操作。它的核心思想是用鏈式調用的方式,取代了傳統的嵌套回調函數。
Promise有三種狀態:pending(進行中)、fulfilled(已成功)、rejected(已失敗)。pending狀態可以轉化為fulfilled或rejected狀態。fulfilled和rejected狀態一旦發生,都不可以再轉化成其他狀態。
二、Promise的基本用法
Promise一般包含在一個函數中,函數返回一個Promise對象。當異步操作執行成功時,Promise對象可以resolve,否則可以reject。
下面是一個例子:
function myAsyncFunc() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("我是成功的數據");
}, 1000);
});
}
調用函數myAsyncFunc可以得到返回值為一個Promise對象,可以使用鏈式調用的方式進行操作,如下:
myAsyncFunc().then(function(data) {
console.log(data);
});
上一步中,使用then方法定義了成功回調函數,這個函數的參數就是resolve傳遞的值。在鏈式調用中,可以使用then方法定義一個或多個回調函數,它們會依次執行。
有時候可能會需要在Promise對象上添加一個失敗處理函數,可以使用catch方法,如下:
myAsyncFunc().then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error);
});
如果myAsyncFunc函數reject了,它將會執行catch定義的函數。
三、Promise的進階用法
1. Promise.all
Promise.all方法接收一個包含Promise對象的數組,當它們全部完成後,Promise.all返回一個新的Promise對象,它的resolve值是一個包含每個Promise對象成功返回值的數組。
如果任何一個Promise對象reject了,這個新的Promise對象就會reject,返回第一個reject的Promise的錯誤信息。
let promise1 = Promise.resolve('數據1');
let promise2 = Promise.resolve('數據2');
let promiseArr = Promise.all([promise1, promise2]);
promiseArr.then(function(data) {
console.log(data);
});
上述代碼會輸出數組[‘數據1’, ‘數據2’]。
2. Promise.race
Promise.race方法接受一個包含Promise對象的數組,返回一個新的Promise對象,這個對象將會與第一個完成的Promise對象保持相同狀態。
如果第一個Promise對象reject了,這個新的Promise對象就會reject,返回第一個reject的Promise的錯誤信息。
let promise1 = new Promise(function(resolve, reject){
setTimeout(function() {
resolve("數據1");
}, 1000);
});
let promise2 = new Promise(function(resolve, reject){
setTimeout(function() {
resolve("數據2");
}, 2000);
});
let promiseArr = Promise.race([promise1, promise2]);
promiseArr.then(function(data) {
console.log(data);
});
在上述代碼中,第一個Promise對象”數據1″會在1秒後resolve,第二個Promise對象”數據2″會在2秒後resolve,但promiseArr會返回第一個resolve的Promise對象”數據1″。
3. Promise.resolve和Promise.reject
Promise.resolve方法返回一個被解析的Promise對象,這個對象處於fulfilled狀態。如果傳入的是一個非Promise對象,它將會被轉化為一個Promise對象,即resolve(obj)等價於返回 new Promise(resolve => resolve(obj))。
Promise.reject方法返回一個被reject的Promise對象,這個對象處於rejected狀態。
let promiseArr = Promise.all([
Promise.resolve('數據1'),
Promise.resolve('數據2'),
Promise.reject('失敗的數據')
]);
promiseArr.then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error);
});
在上述代碼中,其中一個Promise對象返回了reject狀態,所以將會在catch中輸出”失敗的數據”。
四、JSPromise示例
下面是一個基於JSPromise實現流程控制的示例,用於說明在實際開發中如何利用Promise對象進行流程控制。
let request = indexedDB.open('testDB', 1);
let promise = JSPromise();
request.onsuccess = function() {
promise.resolve(request.result);
};
request.onerror = function() {
promise.reject(request.error);
};
request.onupgradeneeded = function() {
let db = request.result;
let objectStore = db.createObjectStore('books', {keyPath: 'id'});
objectStore.createIndex('name', 'name', {unique: false});
};
promise.then(function(db) {
let store = db.transaction('books', 'readwrite').objectStore('books');
return JSPromise(function(resolve) {
store.add({id: 1, name: 'JavaScript設計模式', price: 45.00, publisher: '人民郵電出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
return JSPromise(function(resolve) {
store.add({id: 2, name: 'JavaScript高級程序設計', price: 99.00, publisher: '人民郵電出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
return JSPromise(function(resolve) {
store.add({id: 3, name: 'JavaScript語言精粹', price: 29.00, publisher: '人民郵電出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
let index = store.index('name');
return JSPromise(function(resolve) {
index.get('JavaScript高級程序設計').onsuccess = function(event) {
let object = event.target.result;
resolve(object);
};
});
}).then(function(object) {
console.log(object);
}).catch(function(error) {
console.log(error);
});
上述代碼中,使用indexedDB來存儲一些書籍的數據。在存儲數據過程中,使用了多個Promise對象實現流程控制,從indexedDB打開到操作數據的增刪改查,最後輸出了滿足查詢條件的某一個書籍的信息。
五、總結
通過本文的闡述,我們了解了Promise的基本用法、進階用法,以及一個基於JSPromise的流程控制示例。合理的使用Promise可以讓代碼更加優雅、易讀,增加代碼的可維護性和健壯性。
原創文章,作者:XWHWH,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/370291.html