Promises原理及實現

一、Promise基本概念

Promise 是異步編程的一種解決方案,用於處理異步操作。ES6 的 Promise 規範,是對異步編程的一種規範化,使得編寫和維護異步程序更加容易、直觀。

Promise 是一個對象,它代表了一個異步操作的最終結果。它可以是下列三種狀態之一:等待態(pending)、完成態(fulfilled)、拒絕態(rejected)。

Promise 的優點在於可以避免「回調地獄」,使得代碼結構清晰,更具有可讀性和可維護性。

二、Promise基本用法

ES6 新增了 `Promise` 構造函數,可以使用 `new Promise()` 來創建一個 Promise 對象。

    
        let promise = new Promise(function(resolve, reject){
            //異步操作的代碼
            //成功時調用 resolve()
            //失敗時調用 reject()
        })
    

當 Promise 對象的狀態發生改變時,會產生對應的回調函數。可以使用 `promise.then()` 方法來指定 Promise 對象狀態變為 fulfilled 或 rejected 時調用的回調函數。這兩個方法都返回一個新的 Promise 對象,可以進行鏈式調用。

    
        let promise = new Promise(function(resolve, reject){
            setTimeout(() => resolve("異步操作成功"), 1000);
        })

        promise.then(res => {
            console.log(res); //異步操作成功
        })
    

三、Promise原理

Promise 的基本原理就是對異步操作進行封裝,使其可以返回一個 Promise 對象,並可以使用鏈式調用方法。

我們可以手動模擬一下 Promise 的內部實現:

    
        function Promise_old(fn){
            let state = 'pending';
            let value = null;
            let callbacks = [];

            this.then = function(onFulfilled){
                return new Promise_old(function(resolve){
                    handle({
                        onFulfilled: onFulfilled || null,
                        resolve: resolve
                    })
                })
            }

            function handle(callback){
                if(state === 'pending'){
                    callbacks.push(callback);
                    return;
                }

                if(!callback.onFulfilled){
                    callback.resolve(value);
                    return;
                }

                let ret = callback.onFulfilled(value);
                callback.resolve(ret);
            }

            function resolve(newValue){
                if(newValue && (typeof newValue === 'object' || typeof newValue === 'function')){
                    let then = newValue.then;
                    if(typeof then === 'function'){
                        then.call(newValue, resolve);
                        return;
                    }
                }

                setTimeout(function(){
                    state = 'fulfilled';
                    value = newValue;
                    callbacks.forEach(function(callback){
                        handle(callback);
                    })
                }, 0);
            }

            fn(resolve);
        }
    

上述代碼中,我們定義了 `Promise_old` 構造函數。它內部定義了 `state`、`value`、`callbacks` 三個變量,分別記錄 Promise 對象的當前狀態、結果值和對應回調函數數組。同時我們定義了 `then` 方法,可以使用鏈式調用,將傳入的回調函數壓入 `callbacks` 數組中。

關鍵的 `handle` 函數則利用了 JavaScript 的事件循環機制,當 Promise 對象的狀態從 `pending` 改變時,依次執行隊列中的回調函數。

最後通過 `resolve` 函數,可以修改 Promise 對象的狀態,觸發對應回調函數的執行。

四、Promise實例應用

1、串行異步任務的處理

使用 `Promise` 可以讓多個異步任務按順序執行,比如讀取多個文件,順序進行操作。這裡我們演示一個例子,讀取兩個文件,分別將其內容存放在一個數組中。

    
        let fs = require('fs');

        function readFile(filename){
            return new Promise(function(resolve, reject){
                fs.readFile(filename, 'utf8', function(err, data){
                    if(err){
                        reject(err);
                        return;
                    }
                    resolve(data);
                })
            })
        }

        Promise.all([
            readFile('file1.txt'),
            readFile('file2.txt')
        ]).then(function(dataArr){
            console.log(dataArr); //[data1, data2]
        })
    

2、並發異步任務的處理

有時候需要同時執行多個異步任務,可以使用 `Promise.all()` 方法,將返回值存放在數組中按順序返回。

    
        let dataArr = [];

        function fetchData(url){
            return new Promise((resolve, reject) => {
                fetch(url)
                .then(res => res.json())
                .then(data => {
                    dataArr.push(data);
                    resolve(data);
                })
                .catch(error => reject(error))
            })
        }

        Promise.all([
            fetchData('https://api.xxx.com/1'),
            fetchData('https://api.xxx.com/2'),
            fetchData('https://api.xxx.com/3')
        ]).then(() => {
            console.log(dataArr); //[data1, data2, data3]
        })
    

3、Promise異常處理

使用 `then()` 方法時,可以鏈式調用多個回調函數,並在其中任何一個回調函數中引發錯誤,就會被 `catch()` 方法捕獲。如果在 `then()` 方法中不使用回調函數,就必須在鏈頭使用 `catch()` 方法來進行異常處理。

    
        function fetchData(){
            return new Promise((resolve, reject) => {
                //使用 Math.random() 模擬程序執行時出現錯誤
                if(Math.random() > 0.5){
                    resolve('fetch data success');
                } else {
                    reject('fetch data failed');
                }
            })
        }

        //這個方法捕獲了兩個 Promise 對象中的異常,並輸出錯誤信息
        fetchData().then(res => {
            console.log(res);
        }).catch(error => {
            console.log(error);
        })
    

結束語

Promise 是異步編程的一種新規範,提高了代碼的可讀性、可維護性和穩定性。通過上述的介紹和實例,希望讀者能夠深入了解 Promise 的基本原理和使用方法,高效編寫異步代碼。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/154561.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-16 14:12
下一篇 2024-11-16 14:12

相關推薦

  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • 神經網絡BP算法原理

    本文將從多個方面對神經網絡BP算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP算法簡介 BP算法是一種常用的神經網絡訓練算法,其全稱為反向傳播算法。BP算法的基本思想是通過正…

    編程 2025-04-29
  • GloVe詞向量:從原理到應用

    本文將從多個方面對GloVe詞向量進行詳細的闡述,包括其原理、優缺點、應用以及代碼實現。如果你對詞向量感興趣,那麼這篇文章將會是一次很好的學習體驗。 一、原理 GloVe(Glob…

    編程 2025-04-27
  • 編譯原理語法分析思維導圖

    本文將從以下幾個方面詳細闡述編譯原理語法分析思維導圖: 一、語法分析介紹 1.1 語法分析的定義 語法分析是編譯器中將輸入的字符流轉換成抽象語法樹的一個過程。該過程的目的是確保輸入…

    編程 2025-04-27
  • Python字典底層原理用法介紹

    本文將以Python字典底層原理為中心,從多個方面詳細闡述。字典是Python語言的重要組成部分,具有非常強大的功能,掌握其底層原理對於學習和使用Python將是非常有幫助的。 一…

    編程 2025-04-25
  • Grep 精準匹配:探究匹配原理和常見應用

    一、什麼是 Grep 精準匹配 Grep 是一款在 Linux 系統下常用的文本搜索和處理工具,精準匹配是它最常用的一個功能。Grep 精準匹配是指在一個文本文件中查找與指定模式完…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱「存儲程序控制原理」,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的總線來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25
  • 樸素貝葉斯原理詳解

    一、樸素貝葉斯基礎 樸素貝葉斯是一種基於貝葉斯定理的算法,用於分類和預測。貝葉斯定理是一種計算條件概率的方法,即已知某些條件下,某事件發生的概率,求某條件下另一事件發生的概率。樸素…

    編程 2025-04-25
  • 單點登錄原理

    一、什麼是單點登錄 單點登錄(Single Sign On,SSO)指的是用戶只需要登錄一次,在多個應用系統中使用同一個賬號和密碼登錄,而且在所有系統中都可以使用,而不需要在每個系…

    編程 2025-04-25

發表回復

登錄後才能評論