day02-Promise

来源:https://www.cnblogs.com/liyuelian/archive/2023/01/05/17028904.html
-Advertisement-
Play Games

Promise 1.Promise基本介紹 Promise是非同步編程的一種解決方案,可以解決傳統Ajax回調函數嵌套問題。 傳統的Ajax非同步調用在需要多個操作的時候,會導致多個回調函數嵌套,導致代碼不夠直觀,就是常說的Callback Hell 為瞭解決上述的問題,Promise對象應運而生,在E ...


Promise

1.Promise基本介紹

Promise是非同步編程的一種解決方案,可以解決傳統Ajax回調函數嵌套問題。

  1. 傳統的Ajax非同步調用在需要多個操作的時候,會導致多個回調函數嵌套,導致代碼不夠直觀,就是常說的Callback Hell
  2. 為瞭解決上述的問題,Promise對象應運而生,在EMCAScript 2015當中已經成為標準,Promise也是ES6的新特性
  3. Promise是非同步編程的一種解決方案
  4. 從語法上說,Promise是一個對象,從它可以獲取非同步操作的消息

2.Promise應用實例

2.1需求分析/圖解

  1. 需求:演示promise非同步請求使用

  2. 執行效果:

    image-20230105172853666

2.2代碼實現

使用json文件模擬資料庫表數據

image-20230105201715370

monster.json

{
  "id": 1,
  "name": "黑山老妖"
}

monster_detail_1.json

{
  "id": 1,
  "address": "黑山洞",
  "skill": "翻江倒海",
  "age": 500,
  "gfid": 2
}

monster_gf_2.json

{
  "name": "狐狸精",
  "age": 100
}

2.2.1jquery-ajax實現多次ajax請求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax多次請求</title>
    <!--引入jquery-->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //jquery發出ajax的方式
        $.ajax({
            url: "data/monster.json",
            success(resultData) {//第一次ajax成功的回調函數
                console.log("第一次ajax請求 monster 基本信息=", resultData);
                //發出第二次ajax請求
                $.ajax({
                    //第二次ajax請求的url根據第一次的結果來改變
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {//第二次ajax成功的回調函數
                        console.log("第二次ajax請求 monster 詳細信息=", resultData);
                    },
                    error(err) {
                        console.log("第二次ajax請求出現異常=", err);
                    }
                })
            },
            error(err) {
                console.log("第一次ajax請求出現異常=", err);
            }
        })
    </script>
</head>
<body>

</body>
</html>
image-20230105181356793

使用jquery-ajax的方式容易出現回調函數嵌套(Callback Hell),如果發出的是多次ajax請求,那麼嵌套的層數將會變得非常多,代碼不易讀。這種寫法冗餘度高,代碼可維護性低。

2.2.2promise對象實現多次ajax請求

首先創建一個Promise對象,在該對象內傳入一個箭頭函數,箭頭函數內進行ajax請求。Promise對象的箭頭函數傳入了兩個方法作為參數(命名隨意),這裡的resolve方法是ajax請求成功後調用的函數,reject方法是ajax請求失敗後調用的函數。不同於jquery的回調嵌套,在ajax請求成功的success方法中會調用resolve(),並且把第一次ajax請求獲得的數據傳入該方法。

resolve方法會跳到Promise對象的then()方法,then方法中可以繼續使用$.ajax()去進行第二次ajax請求。在then方法中,又創建了一個Promise對象,該對象和之前的Promise對象中的業務邏輯相似,不同的是可以通過上一次的resolve方法,拿到第一次ajax請求返回的數據,然後根據數據進行第二次的ajax請求.......在第二次的ajax請求中,又可以獲取第二次ajax請求返回的數據,然後調用這次Promise對象的resolve(),將新的數據傳給這次Promise對象的then()方法.....

即,第二次ajax請求的resolve方法又會跳到Promise對象的then()方法........以此類推。

整個過程形成了一個鏈式的調用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用promise完成多次ajax請求</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //先請求到monster.json
        //1.創建Promise對象
        //2.構造函數需要傳入一個箭頭函數
        //3.(resolve, reject)參數列表,resolve:如果請求成功,調用resolve函數
        //                           reject:如果請求失敗,調用reject函數
        //4.箭頭函數體內仍然是通過jquery發出ajax
        let promise = new Promise((resolve, reject) => {
            //發出ajax請求
            $.ajax({
                url: "data/monster.json",
                success(resultData) {//第一次ajax請求成功的回調函數
                    console.log("Promise發出的第一次ajax請求,返回的monster基本信息=", resultData);
                    resolve(resultData);
                },
                error(err) {
                    //console.log("Promise第一次非同步請求出現異常=", err);
                    reject(err);
                }
            })
        });

        //這裡我們可以繼續編寫第一次請求成功之後的業務
        //仍然使用箭頭函數
        promise.then((resultData) => {
            //這裡可以繼續發出請求
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {//第二次ajax請求成功的回調函數
                        console.log("Promise發出的第二次ajax請求,返回的monster詳細信息=", resultData);
                        //可以繼續進行下一次的請求
                        resolve(resultData);
                    },
                    error(err) {
                        //console.log("Promise第二次非同步請求出現異常=", err);
                        reject(err);
                    }
                })
            })
        }).then((resultData) => {
            console.log("promise.then().then(),resultDate", resultData);
            //這裡可以繼續發出第三次ajax請求....
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: `data/monster_gf_${resultData.gfid}.json`,
                    success(resultData) {//第二次ajax請求成功的回調函數
                        console.log("Promise發出的第三次ajax請求,返回的monster gf信息=", resultData);
                        //可以繼續進行下一次的請求
                        //resolve(resultDate);
                    },
                    error(err) {
                        //console.log("Promise第三次次非同步請求出現異常=", err);
                        reject(err);
                    }
                })
            }))

        }).catch((err) => {//這裡可以對多次ajax請求的異常進行處理
            console.log("promise非同步請求異常=", err);
        })
    </script>
</head>
<body>

</body>
</html>
image-20230105201614571

2.2.3promise代碼重排

雖然在2.2.2中使用promise實現了多次ajax請求,解決了jquery-ajax的嵌套回調問題,但是代碼仍然顯得臃腫。創建Promise對象和進行ajax請求的代碼是重覆的,因此可以進行封裝,代碼重排,增強可讀性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise代碼重排</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        /**
         * 這裡我們將重覆的代碼封裝,編寫為get方法
         * @param url ajax請求的資源
         * @param data ajax請求攜帶的數據
         * @returns {Promise<unknown>}
         */
        function get(url, data) {
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success(resultData) {
                        resolve(resultData);
                    },
                    error(err) {
                        reject(err);
                    }
                })
            }))
        }

        //需求:完成
        //1.先獲取monster.json
        //2.再獲取monster_detail_1.json
        //3.再獲取monster_gf_2.json

        get("data/monster.json").then((resultData) => {
            //第一次ajax請求成功後的處理代碼
            console.log("第1次ajax請求返回的數據=", resultData);
            return get(`data/monster_detail_${resultData.id}.json`);

        }).then((resultData) => {
            //第二次ajax請求成功後的處理代碼
            console.log("第2次ajax請求返回的數據=", resultData);
            return get(`data/monster_gf_${resultData.gfid}.json`);

        }).then((resultData) => {
            //第三次ajax請求成功後的處理代碼
            console.log("第3次ajax請求返回的數據=", resultData);
            //如果還有就繼續...

        }).catch(err => {
            console.log("請求出現異常=", err)
        })

    </script>
</head>
<body>

</body>
</html>
image-20230105203402038

3.練習

分別使用Jquery-Ajax和Promise代碼重排,完成如下功能,發出3次ajax請求,獲取對應的數據,註意體會Promise發出多次Ajax請求的方便之處。

image-20230105203724043

student_100.json

{
  "id": 100,
  "name": "jack",
  "class_id": 10
}

class_10.json

{
  "id": 10,
  "name": "java工程師班級",
  "student_num": 30,
  "school_id": 9
}

school_9.json

{
  "id": 9,
  "name": "清華大學",
  "address": "北京"
}

3.1jquery-ajax方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax</title>
    <script type="text/javascript" src="../script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //第一次ajax請求
        $.ajax({
            url: "data/student_100.json",
            success(resultData) {
                console.log("第一次ajax請求=", resultData);
                //第二次ajax請求
                $.ajax({
                    url: `data/class_${resultData.class_id}.json`,
                    success(resultData) {
                        console.log("第二次ajax請求=", resultData);
                        //第三次ajax請求
                        $.ajax({
                            url: `data/school_${resultData.school_id}.json`,
                            success(resultData) {
                                console.log("第三次ajax請求=", resultData);
                            },
                            error(err) {
                                console.log("第三次ajax請求出現異常=", err);
                            }
                        })
                    },
                    error(err) {
                        console.log("第二次ajax請求出現異常=", err);
                    }
                })
            },
            error(err) {
                console.log("第一次ajax請求出現異常=", err);
            }
        })
    </script>
</head>
<body>

</body>
</html>
image-20230105205414203

3.2Promise代碼重排

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise代碼重排</title>
    <script type="text/javascript" src="../script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //get方法也可以封裝到js工具類,重覆使用
        function get(url, data) {
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success(resultData) {
                        resolve(resultData);
                    },
                    error(err) {
                        reject(err);
                    }
                })
            }))
        }

        //業務
        get("data/student_100.json").then(resultData => {
            console.log("第1次返回的數據=", resultData);
            return get(`data/class_${resultData.class_id}.json`);
        }).then(resultData => {
            console.log("第2次返回的數據=", resultData);
            return get(`data/school_${resultData.school_id}.json`);
        }).then(resultData => {
            console.log("第3次返回的數據=", resultData);
            //如有需求可以繼續請求...
        }).catch(err => {
            console.log("promise非同步請求異常=", err)
        })
    </script>
</head>
<body>

</body>
</html>
image-20230105212225703
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在學習stm32的FSMC,打算整一個LCD的驅動,然後封裝的比正點原子更高層一些,方便後期直接調用 然後在學習的時候碰到了一個小問題,研究了一會之後覺得挺有意思的,所以記下來 //使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A6作為數據命令區分線 ...
  • 背景 客戶收到了SQL專家雲告警郵件,在凌晨2點到3點之間帶有資源等待的會話數暴增,請我們協助分析。 現象 登錄SQL專家雲,進入活動會話的趨勢分析頁面,下鑽到2點鐘一個小時內的數據,看到每分鐘的等待數都在100左右,2點15分時達到200。 轉到活動會話原始數據頁面,看到大量會話都在等待,等待類型 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者:蟹黃瓜子 文章來源:GreatSQL社區投稿 1.Zookeeper概述 Zookeeper對於很多人開始可能都有所耳聞,他的使用場景也很多,可以 ...
  • 摘要: RSGroup是集群隔離方案。 本文分享自華為雲社區《華為FusionInsight MRS HBase的集群隔離——RSGroup》,作者: MissAverage。 一、HBase RSGroup理解 RSGroup是集群隔離方案。 HBase原有的資源隔離:為多個用戶共用同一個HBas ...
  • Sqlserver,Mysql基礎SQL語句 SqlServer 建表 CREATE TABLE [IF NOT EXISTS] 表名 ( 欄位名 列類型 [屬性] , 欄位名 列類型 [屬性] , ....... 欄位名 列類型 [屬性] ) ; CREATE TABLE visits ( vis ...
  • 一:背景 1. 講故事 最近在看 SQL SERVER 2008 查詢性能優化,書中說當一個表創建了聚集索引,那麼表中的行會按照主鍵索引的順序物理排列,這裡有一個關鍵詞叫:物理排列,如果不瞭解底層原理,真的會被忽悠過去,其實仔細想一想不可能實現嚴格的 物理排列 ,那對性能是非常大的損害,本篇我們就從 ...
  • https://clickhouse.com/ 概念 ClickHouse 是俄羅斯的 Yandex 於 2016 年開源的列式存儲資料庫(DBMS),使用 C++語言編寫,主要用於線上分析處理查詢(OLAP),能夠使用 SQL 查詢實時生成分析數據報告。 OLAP:一次寫入,多次讀取 ClickH ...
  • 金融業天然就是一個經營數據的行業,一直對數字技術保持高度重視,是數字化轉型最早和數字技術應用最廣的行業之一。在金融和技術融合過程中,數據治理是關鍵。當前金融數據治理已由過去局部數據管理,發展到統籌數據整合、智能應用、數據驅動決策和數據開放融合,這對金融數據治理提出了更高的要求,也帶來新的挑戰。 本期 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...