自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

1. 回調(diào)地域

在學(xué)習(xí) Promise 之前,我們先看一下什么是回調(diào)地獄:

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

  • 獲取產(chǎn)品類別
// 1. 獲取類別信息
const getCategory = () => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: [
      { id: 1, name: "水果" },
      { id: 2, name: "圖書" },
    ],
  };
  return res;
};
  • 根據(jù)類別 id 獲取產(chǎn)品信息
// 2. 根據(jù)類別 id 獲取產(chǎn)品信息
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;
};
  • 根據(jù)產(chǎn)品 id 獲取產(chǎn)品價格
// 3. 根據(jù)產(chǎn)品id獲取產(chǎn)品價格
const getPriceByProductId = (productId) => {
  // 模擬請求
  let res = {
    code: 200,
    message: "請求成功",
    data: { id: 1001, productId: 111, price: 112.23, unitPrice: 1235.23 },
  };
  return res;
};

接下來我們?nèi)カ@取第一個類別下第一個產(chǎn)品的單位價格信息:

let unitPrice = 0.0;
// 獲取產(chǎn)品價格
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;
      }
    }
  }
};

我們發(fā)現(xiàn)在 getProductPrice 這個方法中,第一個請求接口的結(jié)果要作為第二個請求接口的參數(shù),以此類推就會出現(xiàn)層層嵌套,回調(diào)里面套回調(diào),這就是所謂的“回調(diào)地獄”。

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

所以為了解決回調(diào)地獄的問題,提高代碼的可讀性,Promise 應(yīng)運而生。

2. 邂逅 Promise

Promise 是異步編程的一種解決方案。它本質(zhì)上是一個構(gòu)造函數(shù),可以構(gòu)建一個 Promise 對象。

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

Promise 有三種狀態(tài):pending、fulfilled、rejected:

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

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

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

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

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

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

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

3. 使用 Promise

  • 獲取類別信息
const getCategory = () => {
    // 返回結(jié)果封裝成 Promise 對象
    return new Promise((resolve, reject) => {
      // 模擬請求
      let res = {
        code: 200,
        message: "請求成功",
        data: [
          { id: 1, name: "水果" }
        ],
      };
      if (res.code == 200) {
        resolve(res);
      } else {
        reject(res);
      }
    });
  };
  • 根據(jù)類別 id 獲取產(chǎn)品信息
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);
      }
    });
  };
  • 根據(jù)產(chǎn)品 id 獲取產(chǎn)品價格
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);
      }
    });
  };
  • 獲取第一個類別下第一個產(chǎn)品的單位價格信息

Promise 最常用的就是鏈式調(diào)用格式:

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

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

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

4. async 和 await

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

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

語法:

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

舉例:

let unitPrice = 0.0;
// 獲取產(chǎn)品價格
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 實現(xiàn)了異步編程同步化呢?

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

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

5. 答疑

5.1 同步請求和異步請求

同步請求:當發(fā)送一個同步請求時,會暫停后面的代碼執(zhí)行,等待請求的返回結(jié)果,然后再繼續(xù)執(zhí)行下一行代碼。

異步請求:當發(fā)送一個異步請求時,會繼續(xù)執(zhí)行后面的代碼而不會等待請求的返回結(jié)果。當請求完成后,再通過回調(diào)函數(shù)或事件處理函數(shù)來處理返回的數(shù)據(jù)。

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

5.2 promise 和 axios 什么關(guān)系

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

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

5.3 promise 和 async/await 什么關(guān)系

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

2015-10-23 09:34:16

2022-05-04 08:38:32

Netty網(wǎng)絡(luò)框架

2022-12-21 08:04:19

socket圖解網(wǎng)絡(luò)

2024-02-07 12:35:00

React并發(fā)模式concurrent

2022-04-10 19:26:07

TypeScript類型語法

2021-05-11 07:30:58

JNIJavaAPI

2021-01-28 17:41:32

Github網(wǎng)站Pull Reques

2016-03-03 17:42:10

DockerDCOS

2023-12-20 08:23:53

NIO組件非阻塞

2022-11-28 00:04:17

2024-01-15 12:16:37

2024-08-26 14:23:56

2021-12-26 00:01:51

Log4Shell漏洞服務(wù)器

2022-09-06 21:38:45

數(shù)字人數(shù)字孿生

2021-12-16 15:11:59

Facebook天秤幣加密貨幣

2024-07-12 15:08:23

Python@wraps函數(shù)

2024-07-30 08:22:47

API前端網(wǎng)關(guān)

2024-11-08 09:48:38

異步編程I/O密集

2025-04-07 00:49:00

WindowsmacOS微軟

2015-12-01 13:33:51

UnikernelLinux運維
點贊
收藏

51CTO技術(shù)棧公眾號