欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS解決回調(diào)地獄為什么需要Promise來優(yōu)化異步編程

 更新時(shí)間:2023年10月16日 10:50:43   作者:Qing  
這篇文章主要為大家介紹了JS解決回調(diào)地獄為什么需要Promise來優(yōu)化異步編程原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

為什么需要Promise?

JavaScript在執(zhí)行異步操作時(shí),我們并不知道什么時(shí)候完成,但是我們又需要在這個(gè)異步任務(wù)完成后執(zhí)行一系列動(dòng)作,傳統(tǒng)的做法就是使用回調(diào)函數(shù)來實(shí)現(xiàn),下面舉個(gè)常見的例子。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    function loadImage(imgUrl, callback) {
      const img = document.createElement("img");
      img.onload = function () {
        callback(this);
      };
      img.src = imgUrl;
    }

    loadImage(
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg",
      (img) => document.body.appendChild(img)
    );
  </script>
</html>

上面這個(gè)例子會(huì)在圖片加載完成后將圖片放置在body元素下,隨后在頁面上也會(huì)展示出來。
但是如果我們需要在加載完這張圖片后再加載其它的圖片呢,只能在回調(diào)函數(shù)里面再次調(diào)用loadImage

loadImage(
  "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg",
  (img) => {
    document.body.appendChild(img);
    loadImage(
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/8b36f9a7-f780-4e71-b719-9300109a9ff2_product_W572_H370.jpg",
      (img) => {
        document.body.appendChild(img);
      }
    );
  }
);

繼續(xù)增加一張圖片呢?

loadImage(
  "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg",
  (img) => {
    document.body.appendChild(img);
    loadImage(
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/8b36f9a7-f780-4e71-b719-9300109a9ff2_product_W572_H370.jpg",
      (img) => {
        document.body.appendChild(img);
        loadImage(
          "https://travel.12306.cn/imgs/resources/uploadfiles/images/6d77d0ea-53d0-4518-b7e9-e53795b4920c_product_W572_H370.jpg",
          (img) => {
            document.body.appendChild(img);
          }
        );
      }
    );
  }
);

如果按照上述的方式再增加圖片,我們就需要在每層的回調(diào)函數(shù)里面調(diào)用loadImage,就形成了所謂的回調(diào)地獄。

Promise

定義

Promise是一種解決異步編程的方案,它比傳統(tǒng)的異步解決方案更加直觀和靠譜。

狀態(tài)

Promise對(duì)象總共有三種狀態(tài)

  • pending:執(zhí)行中,Promise創(chuàng)建后的初始狀態(tài)。
  • fulfilled:執(zhí)行成功,異步操作成功取得預(yù)期結(jié)果后的狀態(tài)。
  • rejected:執(zhí)行失敗,異步操作失敗未取得預(yù)期結(jié)果后的狀態(tài)。

創(chuàng)建方法

const promise = new Promise((resolve, reject) => {})

Promise構(gòu)造函數(shù)接收一個(gè)函數(shù),這個(gè)函數(shù)可以被稱為執(zhí)行器,這個(gè)函數(shù)接收兩個(gè)函數(shù)作為參數(shù),當(dāng)執(zhí)行器有了結(jié)果后,會(huì)調(diào)用兩個(gè)函數(shù)之一。

  • resolve:在函數(shù)執(zhí)行成功時(shí)調(diào)用,并且把執(zhí)行器獲取到的結(jié)果當(dāng)成實(shí)參傳遞給它,調(diào)用形式如resolve(獲取到的結(jié)果)
  • reject:函數(shù)執(zhí)行失敗時(shí)調(diào)用,并且把具體的失敗原因傳遞給它,調(diào)用形式如reject(失敗原因)

注意:resolve和reject兩個(gè)回調(diào)函數(shù)在Promise類內(nèi)部已經(jīng)定義好函數(shù)體,如果想了解實(shí)現(xiàn)的可以在網(wǎng)上搜索Promise的源碼實(shí)現(xiàn)。

const promise = new Promise((resolve, reject) => {
  /* 做一些需要時(shí)間的事,之后調(diào)用可能會(huì)resolve 也可能會(huì)reject */
  setTimeout(() => {
    const random = Math.random()
    console.log(random)
    if (random > 0.5) {
      resolve('success')
    } else {
      reject('fail')
    }

  }, 500)
})

console.log(promise)

在瀏覽器控制執(zhí)行上面這段代碼

可以看到剛開始promise的狀態(tài)是pending狀態(tài),500ms后promise的狀態(tài)轉(zhuǎn)變?yōu)閞ejected。

狀態(tài)轉(zhuǎn)換

當(dāng)執(zhí)行器獲取到結(jié)果后,并且調(diào)用resolve或者reject兩個(gè)函數(shù)中的一個(gè),整個(gè)promise對(duì)象的狀態(tài)就會(huì)發(fā)生變化。

這個(gè)狀態(tài)的轉(zhuǎn)換過程是不可逆的,一旦發(fā)生轉(zhuǎn)換,狀態(tài)就不會(huì)再發(fā)生變化了。

實(shí)例方法

promise對(duì)象里面有兩個(gè)函數(shù)用來消費(fèi)執(zhí)行器產(chǎn)生的結(jié)果,分別是then和catch,而finally則用來執(zhí)行清理工作。

then

then這個(gè)函數(shù)接收兩個(gè)函數(shù)作為參數(shù),當(dāng)執(zhí)行器傳遞的結(jié)果狀態(tài)是fulfilled,第一個(gè)函數(shù)參數(shù)會(huì)接收到執(zhí)行器傳遞過來的結(jié)果當(dāng)做參數(shù),并且執(zhí)行;當(dāng)執(zhí)行器傳遞的結(jié)果狀態(tài)為rejected,那么作為第二個(gè)函數(shù)參數(shù)會(huì)收到執(zhí)行器傳遞過來的結(jié)果當(dāng)做參數(shù),并且執(zhí)行。

const promise = new Promise((resolve, reject) => {
  /* 做一些需要時(shí)間的事,之后調(diào)用可能會(huì)resolve 也可能會(huì)reject */
  setTimeout(() => {
    const random = Math.random();
    if (random > 0.5) {
      resolve("success");
    } else {
      reject("fail");
    }
  }, 500);
});
console.log(promise);
promise.then(
  (res) => console.log("resolved: ", res),  // 生成的隨機(jī)數(shù)大于0.5,則會(huì)執(zhí)行這個(gè)函數(shù)
  (err) => console.error("rejected: ", err)  // 生成的隨機(jī)數(shù)小于0.5,則會(huì)執(zhí)行這個(gè)函數(shù)
);

可以嘗試多次執(zhí)行上面這段代碼,注意控制臺(tái)打印信息,看是否符合上面的結(jié)論。

如果我們只對(duì)成功的情況感興趣,那么我們可以只為then函數(shù)提供一個(gè)函數(shù)參數(shù)。

const promise = new Promise((resolve) => setTimeout(() => resolve("done"), 1000))

promise.then(console.log) // 1秒后打印done

如果我們只對(duì)錯(cuò)誤的情況感興趣,那么我們可以為then的第一個(gè)參數(shù)提供null,在第二個(gè)參數(shù)提供具體的函數(shù)

const promise = new Promise((resolve, reject) =>
  setTimeout(() => reject("fail"), 1000)
);

promise.then(null, console.log); // 1秒后打印fail

catch

catch這個(gè)函數(shù)接收一個(gè)函數(shù)作為參數(shù),當(dāng)執(zhí)行器傳遞的結(jié)果狀態(tài)為rejected,函數(shù)才會(huì)被調(diào)用。

const promise = new Promise((reject) => setTimeout(() => reject("fail"), 500)).catch(
  console.log
)

promise.catch(console.log)

可能有同學(xué)會(huì)發(fā)現(xiàn),傳遞給catch的參數(shù)好像和傳遞給then的第二個(gè)參數(shù)長得一模一樣,兩種方式有什么差異嗎?
答案是沒有,then(null, errorHandler)catch(errorHandler)這兩種用法都能達(dá)到一樣的效果,都能消費(fèi)執(zhí)行器執(zhí)行失敗時(shí)傳遞的原因。

finally

常規(guī)的try-catch語句有finally語句,在promise中也有finally,它接收一個(gè)函數(shù)作為參數(shù),無論執(zhí)行器得到的結(jié)果狀態(tài)是fulfilled還是rejected,這個(gè)函數(shù)參數(shù)是一定會(huì)被執(zhí)行的。
finally的目的是用來執(zhí)行清理動(dòng)作的,例如請(qǐng)求已經(jīng)完成,停止顯示loading圖標(biāo)。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const random = Math.random();
    if (random > 0.5) {
      resolve("success");
    } else {
      reject("fail");
    }
  }, 500);
});

promise
  .finally((res) => {
    console.log("======res======", res); // 打印undefined
    console.log("task is done, do something");
  })
  .then(console.log, console.error); // 打印success或者fail

通過打印結(jié)果可以確定兩點(diǎn)

  • 傳遞給finally的函數(shù)也不會(huì)接收到執(zhí)行器處理后的結(jié)果。
  • finally函數(shù)不參與對(duì)執(zhí)行器產(chǎn)生結(jié)果的消費(fèi),將執(zhí)行器產(chǎn)生的結(jié)果傳遞給后續(xù)的程序去進(jìn)行消費(fèi)。

手動(dòng)實(shí)現(xiàn)下finally函數(shù),對(duì)上面說到的這兩個(gè)點(diǎn)就會(huì)非常清晰

Promise.prototype._finally = function (callback) {
  return this.then(
    (res) => {
      callback();
      return res;
    },
    (err) => {
      callback();
      throw err;
    }
  );
};

鏈?zhǔn)秸{(diào)用

前面介紹的then、catch以及finally函數(shù)在調(diào)用后都會(huì)返回promise對(duì)象,進(jìn)而可以再次調(diào)用then、catch以及finally,這樣就可以進(jìn)行鏈?zhǔn)秸{(diào)用了。

const promise = new Promise((resolve) => {
  setTimeout(() => resolve(1), 1000);
});

promise
  .then((res) => {
    console.log(res); // 1
    return res * 2;
  })
  .then((res) => {
    console.log(res); // 2
    return res * 2;
  })
  .then((res) => {
    console.log(res); // 4
    return res * 2;
  })
  .then((res) => {
    console.log(res); // 8
  });

我們用鏈?zhǔn)秸{(diào)用的方式來優(yōu)化先前加載圖片的代碼。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    function loadImage(imgUrl) {
      return new Promise((resolve) => {
        const img = document.createElement("img");
        img.onload = function () {
          resolve(this);
        };
        img.src = imgUrl;
      });
    }

    loadImage(
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg"
    )
      .then((img) => {
        document.body.appendChild(img);
        return loadImage(
          "https://travel.12306.cn/imgs/resources/uploadfiles/images/8b36f9a7-f780-4e71-b719-9300109a9ff2_product_W572_H370.jpg"
        );
      })
      .then((img) => {
        document.body.appendChild(img);
        return loadImage(
          "https://travel.12306.cn/imgs/resources/uploadfiles/images/6d77d0ea-53d0-4518-b7e9-e53795b4920c_product_W572_H370.jpg"
        );
      })
      .then((img) => {
        document.body.appendChild(img);
      });
  </script>
</html>
注意:剛剛接觸promise的同學(xué)不要犯下面這種錯(cuò)誤,下面這種代碼也是回調(diào)地獄的例子。
loadImage(
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg"
    ).then((img) => {
      document.body.appendChild(img);
      loadImage(
        "https://travel.12306.cn/imgs/resources/uploadfiles/images/8b36f9a7-f780-4e71-b719-9300109a9ff2_product_W572_H370.jpg"
      ).then((img) => {
        document.body.appendChild(img);
        loadImage(
          "https://travel.12306.cn/imgs/resources/uploadfiles/images/6d77d0ea-53d0-4518-b7e9-e53795b4920c_product_W572_H370.jpg"
        ).then((img) => {
          document.body.appendChild(img);
        });
      });
    });

靜態(tài)方法

Promise.resolve

用來生成狀態(tài)為fulfilled的promise對(duì)象,使用方式如下

const promise = Promise.resolve(1) // 生成值為1的promise對(duì)象

代碼實(shí)現(xiàn)如下

Promise.resolve2 = function (value) {
  return new Promise((resolve) => {
    resolve(value);
  });
};

Promise.reject

用來生成狀態(tài)為rejected的promise對(duì)象,使用方式如下

const promise = Promise.reject('fail')) // 錯(cuò)誤原因?yàn)閒ail的promise對(duì)象

代碼實(shí)現(xiàn)如下

Promise.reject2 = function(value) {
  return new Promise((_, reject) => {
    reject(value)
  })
}

Promise.race

接收一個(gè)可迭代的對(duì)象,并將最先執(zhí)行完成的promise對(duì)象返回。

const promise = Promise.race([
  new Promise((resolve, reject) => setTimeout(() => reject(1), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
])

promise.then(console.log) // 打印2

代碼實(shí)現(xiàn)

Promise.race2 = function (promises) {
  return new Promise((resolve, reject) => {
    if (!promises[Symbol.iterator]) {
      reject(new Error(`${typeof promises} ${promises} is not iterable`));
    }
    for (const promise of promises) {
      Promise.resolve(promise).then(resolve, reject);
    }
  });
};

Promise.all

假設(shè)我們希望并行執(zhí)行多個(gè)promise對(duì)象,并等待所有的promise都執(zhí)行成功。
接收一個(gè)可迭代對(duì)象(通常是promise數(shù)組),當(dāng)?shù)鷮?duì)象里面每個(gè)值都被resolve時(shí),會(huì)返回一個(gè)新的promise,并將結(jié)果數(shù)組進(jìn)行返回。當(dāng)?shù)鷮?duì)象里面有任意一個(gè)值被reject時(shí),直接返回新的promise,其狀態(tài)為rejected。

const promise = Promise.all([
  new Promise((resolve, reject) => setTimeout(() => reject(1), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
])

promise.then(console.log, co sole.error) // console.error打印1

這里需要注意一個(gè)點(diǎn),結(jié)果數(shù)組的順序和源promise的順序是一致的,即使前面的promise耗費(fèi)時(shí)間最長,其結(jié)果也會(huì)放置在結(jié)果數(shù)組第一個(gè)。

const promise = Promise.all([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
])

promise.then(console.log) // 打印結(jié)果[1, 2, 3]

我們針對(duì)圖片加載的例子使用Promise.all來實(shí)現(xiàn)。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    function loadImage(imgUrl) {
      return new Promise((resolve) => {
        const img = document.createElement("img");
        img.onload = function () {
          resolve(this);
        };
        img.src = imgUrl;
      });
    }
    const imgUrlList = [
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/1716878f-79a2-4db1-af8c-b9c2039f0b3c_product_W572_H370.jpg",
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/8b36f9a7-f780-4e71-b719-9300109a9ff2_product_W572_H370.jpg",
      "https://travel.12306.cn/imgs/resources/uploadfiles/images/6d77d0ea-53d0-4518-b7e9-e53795b4920c_product_W572_H370.jpg",
    ];
    const promiseList = imgUrlList.map((item) => loadImage(item));
    const promise = Promise.all(promiseList).then((imglist) => {
      imglist.forEach((item) => document.body.appendChild(item));
    });
  </script>
</html>

代碼實(shí)現(xiàn)

Promise.all2 = function (promises) {
  return new Promise((resolve, reject) => {
    if (!promises[Symbol.iterator]) {
      reject(new Error(`${typeof promises} ${promises} is not iterable`));
    }
    const len = promises.length;
    const result = new Array(len);
    let count = 0;
    if (!len) {
      resolve(result);
      return;
    }
    for (let i = 0; i < promises.length; i++) {
      Promise.resolve(promises[i]).then(
        (res) => {
          count++;
          result[i] = res;  // 保證結(jié)果數(shù)組的放置順序
          if (count === len) {
            resolve(result);
          }
        },
        (err) => {
          reject(err);
        }
      );
    }
  });
};

Promise.allSettled

前面提到的Promise.all遇到任意一個(gè)promise reject,那么Promise.all會(huì)直接返回一個(gè)rejected的promise對(duì)象。而Promise.allSetled只需要等待迭代對(duì)象內(nèi)所有的值都完成了狀態(tài)的轉(zhuǎn)變,無論迭代對(duì)象里面的值是被resolve還是reject,那么就會(huì)返回一個(gè)狀態(tài)為fulfilled的promise對(duì)象,并以包含對(duì)象數(shù)組的形式返回結(jié)果。

const promise = Promise.allSettled([
  new Promise((resolve, reject) => setTimeout(() => reject(1), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)),
]);

promise.then(console.log, console.error); 

// 打印結(jié)果

// [
//   { status: 'rejected', reason: 1 },
//   { status: 'fulfilled', value: 2 },
//   { status: 'fulfilled', value: 3 }
// ]

代碼實(shí)現(xiàn)

Promise.allSettled2 = function (promises) {
  const resolveHandler = (res) => ({ status: "fulfilled", value: res });
  const rejectHandler = (err) => ({ status: "rejected", reason: err });
  return Promise.all(
    promises.map((item) => item.then(resolveHandler, rejectHandler))
  );
};

使用場景

大多數(shù)異步任務(wù)場景都可以使用promise,例如網(wǎng)絡(luò)請(qǐng)求、文件操作、數(shù)據(jù)庫操作等。當(dāng)然不是所有的異步任務(wù)場景都適合使用promise,例如在事件驅(qū)動(dòng)的編程模型中,使用時(shí)間監(jiān)聽器和觸發(fā)器來處理異步操作更加自然和直觀。

在JavaScript中,async和await提供基于promise更高級(jí)的異步編程方式,其使用方式看起來就像同步操作一樣,更加直觀。在使用promise的同時(shí),可以配合async和await體驗(yàn)更好的異步編程。

一個(gè)小問題

我們前面在講catch的時(shí)候說到了,catch(errorHandler)其實(shí)就是then(null, errorHandler)的簡寫,那么下面兩種寫法會(huì)有區(qū)別嗎?

// 寫法1
promise.then(resolveHandler, rejectHandler)

// 寫法2
promise.then(resolveHandler).catch(rejectHandler)

答案是不一樣,假如在resolveHandler里面拋出錯(cuò)誤,寫法1最終會(huì)獲得一個(gè)rejected的promise,而寫法二由于后續(xù)有catch方法,所以即使f1里面有拋出異常,也能得到處理。

以上就是JS解決回調(diào)地獄為什么需要Promise來優(yōu)化異步編程的詳細(xì)內(nèi)容,更多關(guān)于JS Promise異步編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在JavaScript中使用JSON數(shù)據(jù)

    在JavaScript中使用JSON數(shù)據(jù)

    JSON 是 JavaScript 原生格式,這意味著 在 JavaScript 中處理 JSON 數(shù)據(jù)不需要任何特殊的 API 或工具包,接下來由腳本之家小編給大家介紹在JavaScript中使用JSON數(shù)據(jù)的方法,感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • layui 實(shí)現(xiàn)table翻頁滾動(dòng)條位置保持不變的例子

    layui 實(shí)現(xiàn)table翻頁滾動(dòng)條位置保持不變的例子

    今天小編就為大家分享一篇layui 實(shí)現(xiàn)table翻頁滾動(dòng)條位置保持不變的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • ES6入門教程之Array.from()方法

    ES6入門教程之Array.from()方法

    這篇文章主要給大家介紹了關(guān)于ES6入門教程之Array.from()方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用ES6具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • JavaScript類庫D

    JavaScript類庫D

    D類庫是以為當(dāng)前成熟框架、類庫開發(fā)輔助類庫的目標(biāo)而被開發(fā)。
    2010-10-10
  • js實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能

    js實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能

    本文主要介紹了js實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能的示例。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • javascript設(shè)計(jì)模式 – 抽象工廠模式原理與應(yīng)用實(shí)例分析

    javascript設(shè)計(jì)模式 – 抽象工廠模式原理與應(yīng)用實(shí)例分析

    這篇文章主要介紹了javascript設(shè)計(jì)模式 – 抽象工廠模式,結(jié)合實(shí)例形式分析了javascript抽象工廠模式相關(guān)概念、原理、定義、應(yīng)用場景及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的八種方式

    JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的八種方式

    這篇文章介紹了JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的八種方式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 關(guān)于JS控制代碼暫停的實(shí)現(xiàn)方法分享

    關(guān)于JS控制代碼暫停的實(shí)現(xiàn)方法分享

    關(guān)于JS控制代碼暫停的工作總結(jié),需要的朋友可以參考下
    2012-10-10
  • 在TypeScript項(xiàng)目中搭配Axios封裝后端接口調(diào)用

    在TypeScript項(xiàng)目中搭配Axios封裝后端接口調(diào)用

    這篇文章主要介紹了在TypeScript項(xiàng)目中搭配Axios封裝后端接口調(diào)用,本文記錄一下在?TypeScript?項(xiàng)目里封裝?axios?的過程,之前在開發(fā)?StarBlog-Admin?的時(shí)候已經(jīng)做了一次封裝,不過那時(shí)是JavaScript跟TypeScript還是有些區(qū)別的,需要的朋友可以參考下
    2024-01-01
  • JS前端認(rèn)證授權(quán)技巧歸納總結(jié)

    JS前端認(rèn)證授權(quán)技巧歸納總結(jié)

    這篇文章主要為大家介紹了JS前端認(rèn)證授權(quán)技巧歸納總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論