JSPromise詳解

一、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-hk/n/370291.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
XWHWH的頭像XWHWH
上一篇 2025-04-20 13:09
下一篇 2025-04-20 13:09

相關推薦

  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • 神經網絡代碼詳解

    神經網絡作為一種人工智能技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網絡的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網絡模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web服務器。nginx是一個高性能的反向代理web服務器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分佈式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性傳感器,能夠同時測量加速度和角速度。它由三個傳感器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變量讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25
  • C語言貪吃蛇詳解

    一、數據結構和算法 C語言貪吃蛇主要運用了以下數據結構和算法: 1. 鏈表 typedef struct body { int x; int y; struct body *nex…

    編程 2025-04-25

發表回復

登錄後才能評論