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

詳解JS如何使用Promise緩存網(wǎng)絡(luò)請求

 更新時間:2023年12月12日 11:05:44   作者:慕仲卿  
網(wǎng)絡(luò)請求是現(xiàn)代Web應(yīng)用中的常見操作,很多時候需要獲取服務(wù)器上的數(shù)據(jù),在進(jìn)行網(wǎng)絡(luò)請求時,為了減輕服務(wù)器的壓力,緩存策略常被用來避免對同一數(shù)據(jù)的重復(fù)請求,本文將探討如何使用Promise結(jié)合緩存來高效處理網(wǎng)絡(luò)請求,需要的朋友可以參考下

背景與概念

在進(jìn)行網(wǎng)絡(luò)請求的應(yīng)用中,尤其是數(shù)據(jù)變化不頻繁的場景下,緩存是一個常用而有效的優(yōu)化手段。緩存可以減少網(wǎng)絡(luò)延遲,避免不必要的數(shù)據(jù)傳輸,節(jié)省帶寬,提高用戶體驗(yàn)。但是,不當(dāng)?shù)木彺娌呗钥赡軐?dǎo)致用戶看到過時的數(shù)據(jù)。因此,實(shí)現(xiàn)一個合理的緩存策略是非常重要的。

Promise是JavaScript中處理異步操作的一種模式,它代表一個尚未完成但預(yù)計將來會完成的操作。通過Promise,可以將異步操作隊(duì)列化,鏈?zhǔn)教幚?,并在適當(dāng)?shù)臅r候進(jìn)行錯誤處理。

緩存網(wǎng)絡(luò)請求的需求與挑戰(zhàn)

在許多情況下,當(dāng)多個組件或者頁面需要相同的數(shù)據(jù)時,每個組件各自發(fā)起網(wǎng)絡(luò)請求顯得非常低效。這需要一種機(jī)制能夠“共享”已經(jīng)發(fā)起的請求,當(dāng)請求完成后,所有需要這份數(shù)據(jù)的組件都能獲得到。同時,若數(shù)據(jù)已經(jīng)在本地緩存,則無需重新發(fā)起網(wǎng)絡(luò)請求,直接使用緩存數(shù)據(jù)即可。

實(shí)現(xiàn)這樣的功能,有如下幾個挑戰(zhàn):

  • 請求的復(fù)用性:避免同一數(shù)據(jù)的重復(fù)請求。
  • 請求的并發(fā)管理:針對相同的數(shù)據(jù)來源同一時間只發(fā)送一次請求。
  • 緩存的合理性:緩存有效數(shù)據(jù),但要避免過時數(shù)據(jù)的問題。
  • 緩存的容錯性:當(dāng)請求失敗時,如何處理以及如何通知依賴這份數(shù)據(jù)的其他部分。

Promise緩存網(wǎng)絡(luò)請求的實(shí)現(xiàn)

具體到實(shí)現(xiàn),可以創(chuàng)建一個緩存對象,用于存儲已經(jīng)發(fā)起的請求的Promise對象。在請求發(fā)起前,先檢查緩存中是否已存在相應(yīng)的Promise;如果存在,直接返回該P(yáng)romise;如果不存在,則發(fā)起新的請求,并將請求的Promise存儲到緩存中。

以下是一個簡化的實(shí)現(xiàn)示例,逐一解釋核心代碼:

import utils from '@/utils';

export const reqThenCacheData = (
  name: string
): Promise<void | Promise<utils.ICachedData>> => {
  // 嘗試獲取緩存數(shù)據(jù)
  const cache = utils.cacheForData.get(name);

  // 如果存在緩存,直接返回緩存中的Promise對象 
  if (cache) return cache;

  // 沒有緩存,構(gòu)造請求URL,發(fā)起網(wǎng)絡(luò)請求
  const url = `http://*******?name=${name}`;
  const currentHandler = (
    request.get({ url }) as unknown as Promise<Array<utils.ICachedListData>>
  )
    .then((data: Array<utils.ICachedListData>) => {
      // 對返回的數(shù)據(jù)進(jìn)行處理,得到一個子請求列表
      const subList: Array<string> = data.map((sub) => {
        if (sub.is_default === 1) return sub.subName;
      });
      return subList.filter((item) => item);
    })
    .then((subNames: Array<string>) => {
      // 根據(jù)第一次請求的結(jié)果,構(gòu)建第二次請求的Promise數(shù)組
      const subRequestPromises: Array<Promise<utils.ICachedData>> = subNames.map((subName: string) => {
        const subUrl = `http://*******?subName=${subName}`;
        return request.get({ url: subUrl }) as unknown as Promise<utils.ICachedData>;
      });
      // 使用Promise.all等待所有子請求完成
      return Promise.all(subRequestPromises);
    })
    .then((subData: Array<utils.ICachedData>) => {
      // 可以進(jìn)一步處理所有子請求的結(jié)果
      // 示例僅返回其中一個子請求結(jié)果
      return subData[0];
    })
    .catch((error) => {
      console.log('請求數(shù)據(jù)失?。?, error);
      // 錯誤處理:可以決定是否從緩存中移除錯誤的Promise
      utils.cacheForData.delete(name);
      // 根據(jù)需要,可以在這里拋出錯誤或返回一個默認(rèn)值
      throw error;
    });

  // 存入緩存,便于下次直接使用
  utils.cacheForData.set(name, currentHandler);
  return currentHandler;
};

緩存邏輯概述

上述代碼演示了基于Promise的網(wǎng)絡(luò)請求緩存機(jī)制。首先,通過調(diào)用cacheForData.get(name)嘗試獲取緩存中已存在的請求Promise,如果找到,則直接返回,避免重復(fù)請求。

如果緩存中沒有找到請求Promise,那么將發(fā)起一個新的網(wǎng)絡(luò)請求。請求返回的Promise通過鏈?zhǔn)降?code>.then()方法進(jìn)行處理。這些.then()方法負(fù)責(zé)對返回的數(shù)據(jù)進(jìn)行處理和轉(zhuǎn)化,使用者可以根據(jù)實(shí)際情況添加具體的數(shù)據(jù)處理邏輯。

最后,使用catch()方法處理可能發(fā)生的錯誤,并且將當(dāng)前請求的Promise對象使用cacheForData.set(name, currentHandler)方法存儲到緩存中,以便后續(xù)重用。

多階段請求處理

上述代碼展示了如何處理一個需要多次網(wǎng)絡(luò)請求的場景。系統(tǒng)首先檢查緩存中是否有目標(biāo)數(shù)據(jù)的Promise,在緩存未命中時,發(fā)起一個初始網(wǎng)絡(luò)請求。取得初始數(shù)據(jù)后,提取必要的信息組成新的請求數(shù)組。

利用Promise.all()方法,可以并行處理多個網(wǎng)絡(luò)請求,這個方法返回一個新的Promise,它將在所有請求完成時解析。這一過程是Promise緩存實(shí)現(xiàn)的核心,它使得各個請求之間可以共享狀態(tài),并在全部請求都完成后統(tǒng)一返回結(jié)果。

這種緩存策略的一個關(guān)鍵優(yōu)勢在于它的復(fù)用性和并發(fā)管理能力。即使有多個請求同時要求相同的資源,由于緩存機(jī)制的存在,真實(shí)的網(wǎng)絡(luò)請求只會發(fā)生一次。每個后續(xù)嘗試訪問此數(shù)據(jù)的操作都會得到一個掛起的Promise,而非觸發(fā)新的網(wǎng)絡(luò)請求。

緩存及請求細(xì)節(jié)處理

在網(wǎng)絡(luò)請求Promise后串聯(lián)多個.then()方法時,是在處理與轉(zhuǎn)換原始請求返回的數(shù)據(jù)。示例中,首先處理的是將返回的列表按照特定條件篩選,然后對篩選后的結(jié)果進(jìn)行進(jìn)一步的請求。這里的關(guān)鍵是Promise.all(),它確保了同時處理多個異步操作。

處理器currentHandler的最后結(jié)果是一個新的Promise,它代表了一系列依賴于原始請求并經(jīng)過一定處理的數(shù)據(jù)。這個Promise作為最終結(jié)果,將被緩存并返回給調(diào)用者。

緩存和請求的一個重要細(xì)節(jié)是錯誤處理。當(dāng)請求出現(xiàn)錯誤時,通常不應(yīng)該將錯誤的Promise存儲到緩存中,因?yàn)檫@可能導(dǎo)致后續(xù)所有對該數(shù)據(jù)的請求都會立即返回錯誤。相反,可以選擇在錯誤處理邏輯中移除緩存項(xiàng),或者采取其他的恢復(fù)機(jī)制。

緩存策略的考慮

實(shí)現(xiàn)緩存時,還需要考慮它的有效性和過時機(jī)制。只有當(dāng)數(shù)據(jù)不頻繁變化或者對即時性要求不高的情況下,緩存才是合理的。尤其是在一些數(shù)據(jù)更新周期較長的場景,例如一些配置數(shù)據(jù)、用戶信息等,使用緩存能帶來顯著的性能提升。

有時候,需要設(shè)立緩存過期機(jī)制,即數(shù)據(jù)在緩存中存儲一段時間后失效,之后的請求將強(qiáng)制發(fā)起新的網(wǎng)絡(luò)請求以獲取最新數(shù)據(jù)。緩存過期機(jī)制可以通過定時器或者請求次數(shù)等方式來實(shí)現(xiàn)。

結(jié)語

合理地使用Promise和緩存可以顯著提升應(yīng)用的性能,減輕服務(wù)器的負(fù)擔(dān),并提供更加流暢的用戶體驗(yàn)。通過在正確的地方引入緩存,可以有效地避免不必要的網(wǎng)絡(luò)請求,加快數(shù)據(jù)的加載速度。在此基礎(chǔ)上,合理設(shè)置緩存失效機(jī)制,能夠確保用戶始終獲取到最新的數(shù)據(jù),避免緩存導(dǎo)致的數(shù)據(jù)過時問題。

通過上述示例的實(shí)踐,開發(fā)者可以根據(jù)自身應(yīng)用的需要,定制適合自己業(yè)務(wù)場景的網(wǎng)絡(luò)請求緩存方案。這不僅可以提高程序性能,還可以增加程序的魯棒性,優(yōu)化用戶的交互體驗(yàn)。

以上就是詳解JS如何使用Promise緩存網(wǎng)絡(luò)請求的詳細(xì)內(nèi)容,更多關(guān)于JS Promise緩存網(wǎng)絡(luò)請求的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容

    javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容

    這篇文章主要介紹了javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁內(nèi)容,需要的朋友可以參考下
    2014-12-12
  • JS中的hasOwnProperty()和isPrototypeOf()屬性實(shí)例詳解

    JS中的hasOwnProperty()和isPrototypeOf()屬性實(shí)例詳解

    hasOwnProperty()和isPrototypeOf()這兩個屬性都是Object.prototype所提供:Object.prototype.hasOwnProperty()和Object.prototype.isPropertyOf(),下面給大家介紹這兩個屬性的方法和使用,一起看下吧
    2016-08-08
  • 小程序?qū)崿F(xiàn)日歷效果

    小程序?qū)崿F(xiàn)日歷效果

    這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)日歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • js實(shí)現(xiàn)的早期滑動門菜單效果代碼

    js實(shí)現(xiàn)的早期滑動門菜單效果代碼

    這篇文章主要介紹了js實(shí)現(xiàn)的早期滑動門菜單效果代碼,涉及javascript數(shù)組遍歷及通過鼠標(biāo)事件動態(tài)改變頁面元素屬性的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • 深入理解JavaScript中的尾調(diào)用(Tail Call)

    深入理解JavaScript中的尾調(diào)用(Tail Call)

    尾調(diào)用(Tail Call)是函數(shù)式編程的一個重要概念,下面這篇文章主要給大家深入的介紹了關(guān)于JavaScript中尾調(diào)用的相關(guān)資料,文中介紹的非常詳細(xì),相信對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。
    2017-02-02
  • 原生js實(shí)現(xiàn)的觀察者和訂閱者模式簡單示例

    原生js實(shí)現(xiàn)的觀察者和訂閱者模式簡單示例

    這篇文章主要介紹了原生js實(shí)現(xiàn)的觀察者和訂閱者模式,結(jié)合簡單實(shí)例形式分析了js觀察者和訂閱者模式的相關(guān)原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2020-04-04
  • JavaScript中使用參數(shù)個數(shù)實(shí)現(xiàn)重載功能

    JavaScript中使用參數(shù)個數(shù)實(shí)現(xiàn)重載功能

    這篇文章主要介紹了JavaScript中使用參數(shù)個數(shù)實(shí)現(xiàn)重載功能,需要的朋友可以參考下
    2017-09-09
  • ES6中Set和Map用法實(shí)例詳解

    ES6中Set和Map用法實(shí)例詳解

    這篇文章主要介紹了ES6中Set和Map用法,結(jié)合實(shí)例形式詳細(xì)分析了ES6中Set和Map的基本功能、原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • JavaScript獲取瀏覽器窗口尺寸的幾種方法

    JavaScript獲取瀏覽器窗口尺寸的幾種方法

    JavaScript是一種廣泛使用的腳本語言,用于開發(fā)網(wǎng)頁和應(yīng)用程序,在Web開發(fā)中,經(jīng)常需要獲取瀏覽器窗口的尺寸,以便根據(jù)窗口大小進(jìn)行布局或執(zhí)行其他操作,本文將介紹如何使用JavaScript來獲取瀏覽器窗口尺寸,需要的朋友可以參考下
    2023-11-11
  • 深入理解javascript構(gòu)造函數(shù)和原型對象

    深入理解javascript構(gòu)造函數(shù)和原型對象

    對象,是javascript中非常重要的一個梗,是否能透徹的理解它直接關(guān)系到你對整個javascript體系的基礎(chǔ)理解,說白了,javascript就是一群對象在攪。。(嗶!)。
    2014-09-09

最新評論