成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Promise到底是個啥?你知道嗎?

開發 前端
Promise 對 axios 的返回結果進行了封裝。所以當你發送一個 axios 請求,會返回一個 Promise 對象。然后你就可以調用 .then、.catch方法了。

1. 回調地域

在學習 Promise 之前,我們先看一下什么是回調地獄:

這里我們模擬三個請求接口:

  • 獲取產品類別
// 1. 獲取類別信息
const getCategory = () => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: [
      { id: 1, name: "水果" },
      { id: 2, name: "圖書" },
    ],
  };
  return res;
};
  • 根據類別 id 獲取產品信息
// 2. 根據類別 id 獲取產品信息
const getProductByCategoryId = (categoryId) => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: [
      { id: 111, categoryId: 1, name: "蘋果" },
      { id: 112, categoryId: 1, name: "香蕉" },
      { id: 113, categoryId: 1, name: "百香果" },
    ],
  };
  return res;
};
  • 根據產品 id 獲取產品價格
// 3. 根據產品id獲取產品價格
const getPriceByProductId = (productId) => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: { id: 1001, productId: 111, price: 112.23, unitPrice: 1235.23 },
  };
  return res;
};

接下來我們去獲取第一個類別下第一個產品的單位價格信息:

let unitPrice = 0.0;
// 獲取產品價格
const getProductPrice = () => {
  let categoryRes = getCategory();
  if (categoryRes.code === 200) {
    let produceRes = getProductByCategoryId(1);
    if (produceRes.code === 200) {
      let priceRes = getPriceByProductId(1);
      if (priceRes.code === 200) {
        unitPrice = res.data.unitPrice;
      }
    }
  }
};

我們發現在 getProductPrice 這個方法中,第一個請求接口的結果要作為第二個請求接口的參數,以此類推就會出現層層嵌套,回調里面套回調,這就是所謂的“回調地獄”。

如果請求的接口太多,那代碼寫起來可就太苦逼了,就跟套娃一樣。

所以為了解決回調地獄的問題,提高代碼的可讀性,Promise 應運而生。

2. 邂逅 Promise

Promise 是異步編程的一種解決方案。它本質上是一個構造函數,可以構建一個 Promise 對象。

Promise 構造函數接受一個函數作為參數,該函數的兩個參數分別是 resolve 和 reject 。對象上有 then、catch、finall 方法。

Promise 有三種狀態:pending、fulfilled、rejected:

  • pending:它的意思是待定的,相當于是一個初始狀態。創建 Promise 對象時就是一個初始狀態。
  • fulfilled:成功。當調用 resolved 方法后,Promise 對象的狀態就會從 pending 切換到 fulfilled,且不可改變。
  • rejected:失敗。當調用 reject 方法后,Promise 對象的狀態就會從 pending 切換到 reject,且不可改變。

看了上面的解釋,你可能還是有點懵逼,接下來我用通俗易懂的語言解釋一下 Promise 是個什么玩意:

1.Promise 就是一個用來封裝 HTTP 請求的工具。

2.我們請求后臺接口獲取數據,如果請求成功,就調用 Promise 的 resolve 方法,并將返回的數據作為該方法的參數。如果請求失敗,就調用 Promise 的 reject 方法,并將返回的錯誤信息作為該方法的參數。

3.然后我們將一個 Promise 對象作為該請求接口的返回值返回。

4.因為該接口返回一個 Promise 對象,所以我們調用該接口的時候就可以直接用.then()處理成功的信息,用 .catch() 處理失敗的信息了。

接下來我們將上面的例子用 Promise 改造一下,有了真實案例,大家對 Promise 的理解就更清晰明了了。

3. 使用 Promise

  • 獲取類別信息
const getCategory = () => {
    // 返回結果封裝成 Promise 對象
    return new Promise((resolve, reject) => {
      // 模擬請求
      let res = {
        code: 200,
        message: "請求成功",
        data: [
          { id: 1, name: "水果" }
        ],
      };
      if (res.code == 200) {
        resolve(res);
      } else {
        reject(res);
      }
    });
  };
  • 根據類別 id 獲取產品信息
const getProductByCategoryId = (categoryId) => {
    return new Promise((resolve, reject) => {
      // 模擬請求
      let res = {
        code: 200,
        message: "請求成功",
        data: [
          { id: 111, categoryId: 1, name: "蘋果" },
          { id: 112, categoryId: 1, name: "香蕉" },
          { id: 113, categoryId: 1, name: "百香果" },
        ],
      };
      if (res.code == 200) {
        resolve(res);
      } else {
        reject(res);
      }
    });
  };
  • 根據產品 id 獲取產品價格
const getPriceByProductId = (productId) => {
    return new Promise((resolve, reject) => {
      // 模擬請求
      let res = {
        code: 200,
        message: "請求成功",
        data: { id: 1001, productId: 111, price: 112.23, unitPrice: 1235.23 },
      };
      if (res.code == 200) {
        resolve(res);
      } else {
        reject(res);
      }
    });
  };
  • 獲取第一個類別下第一個產品的單位價格信息

Promise 最常用的就是鏈式調用格式:

let unitPrice = 0.0;
  // 獲取產品價格
  const getProductPrice = () => {
    getCategory().then(res => {
      // 類別 id
      let id = res.data[0].id;
      // 返回一個 Promise 對象
      return getProductByCategoryId(id);
    }).then(res => {
      // 產品 id
      let id = res.data[0].id;
      return getPriceByProductId(id);
    }).then(res => {
      unitPrice = res.data.unitPrice;
    })
  };

當然我們在日常使用過程中一般都是這種格式:

getMethod().then(res => {
  // 請求成功
  }).catch(error=>{
  // 異常
  }).finally(()=>{
  // 不管成功還是異常都要執行
  })

4. async 和 await

雖然有了 Promise 之后,代碼的可讀性有了很大提高。但是 ES7 又引入了 async 和 await 來簡化 Promise 調用操作,實現了以異步操作像同步的方式去執行。

說白了async 和 await 就是對 Promise 進行了封裝。

語法:

await 和 async 是成對出現的,如果寫了 await 必須要寫 async,否則會報錯。如果只寫 async,那返回的就是一個 Promise 對象

舉例:

let unitPrice = 0.0;
// 獲取產品價格
const getProductPrice = async () => {
  let res1 = await getCategory();
  let categoryId = res1.data[0].id;
  let re2 = await getProductByCategoryId(categoryId);
  let productId = re2.data[0].id;
  let re3 = await getPriceByProductId(productId);
  unitPrice = res3.data.unitPrice;
};

如果只寫 async,返回的就是一個 Promise 對象

const getProductPrice = async () => {
  getCategory().then(res=>{
    let categoryId =  res.data[0].id
  })
};
const getCategory = async () => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: [
      { id: 1, name: "水果" },
      { id: 2, name: "圖書" },
    ],
  };
  return res;
};

那為什么說 async 和 await 實現了異步編程同步化呢?

因為 await 這個命令的意思就是等這一行的異步方法執行成功后,然后才能執行下一行代碼,否則就一直等待,下面的代碼就執行不了。

所以雖然請求后臺的接口是異步的,但是 await 在語法層面實現了同步。

5. 答疑

5.1 同步請求和異步請求

同步請求:當發送一個同步請求時,會暫停后面的代碼執行,等待請求的返回結果,然后再繼續執行下一行代碼。

異步請求:當發送一個異步請求時,會繼續執行后面的代碼而不會等待請求的返回結果。當請求完成后,再通過回調函數或事件處理函數來處理返回的數據。

  • 同步請求就會依次打印:1、2。如果第一個方法執行時間比較長,那就一直等待。
const getProductPrice =  () => {
    console.log("1")
};
console.log("2")
  • 異步請求可能會先打印 2,后打印 1。
const getProductPrice = async  () => {
    console.log("1")
};
console.log("2")

5.2 promise 和 axios 什么關系

Promise 是 JavaScript 中用于異步編程的一個對象,而 axios 是 用來發送 HTTP 請求的工具庫。

Promise 對 axios 的返回結果進行了封裝。所以當你發送一個 axios 請求,會返回一個 Promise 對象。然后你就可以調用 .then、.catch方法了。

5.3 promise 和 async/await 什么關系

  • async/await 對 promise 進行了封裝。
  • async/await 是用同步語法去獲取異步請求,徹底消滅回調函數。
  • 只有 async,返回的是 Promise 對象。
  • await 相當于 Promise 的 then
責任編輯:武曉燕 來源: 知否技術
相關推薦

2015-10-23 09:34:16

2022-05-04 08:38:32

Netty網絡框架

2022-12-21 08:04:19

socket圖解網絡

2024-02-07 12:35:00

React并發模式concurrent

2023-12-20 08:23:53

NIO組件非阻塞

2016-03-03 17:42:10

DockerDCOS

2022-04-10 19:26:07

TypeScript類型語法

2021-05-11 07:30:58

JNIJavaAPI

2021-01-28 17:41:32

Github網站Pull Reques

2022-11-28 00:04:17

2024-01-15 12:16:37

2024-07-30 08:22:47

API前端網關

2024-11-08 09:48:38

異步編程I/O密集

2025-04-07 00:49:00

WindowsmacOS微軟

2015-12-01 13:33:51

UnikernelLinux運維

2021-12-26 00:01:51

Log4Shell漏洞服務器

2024-08-26 14:23:56

2021-12-16 15:11:59

Facebook天秤幣加密貨幣

2022-09-06 21:38:45

數字人數字孿生

2024-07-12 15:08:23

Python@wraps函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩国产中文字幕 | 久久青青| 羞羞视频在线观看 | 国产网站在线播放 | 国产亚洲一区二区三区在线观看 | 精品视频国产 | 国产精品视频在线免费观看 | 涩涩视频在线播放 | 一区二区三区四区国产精品 | 天天操人人干 | 欧美一级做性受免费大片免费 | 欧美精品91 | 91看片在线 | 亚洲成人蜜桃 | 日韩一级免费观看 | 国产精品久久精品 | 日韩三极 | 天天干天天玩天天操 | 欧美福利| 成人影院在线视频 | 免费看欧美一级片 | 久久久精品日本 | 国产欧美精品一区二区三区 | 国产福利在线 | 综合精品久久久 | 欧美视频 亚洲视频 | 亚洲激情av | 欧美国产精品一区二区三区 | 午夜精品久久久 | 99久久精品免费看国产四区 | 色婷婷综合网 | 日韩av在线一区 | 免费看的黄网站 | 久久精品中文字幕 | 日日操操 | 在线观看av中文字幕 | 成人h片在线观看 | 嫩草视频在线看 | 成人国产免费视频 | 亚洲精品乱码久久久久久久久久 | 一区二区三区在线免费观看 |