最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript實現一個Promise隊列小工具

 更新時間:2022年09月01日 14:47:04   作者:小樹ZW???????  
這篇文章主要介紹了JavaScript實現一個Promise隊列小工具,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

摘要

在百度的解釋中,隊列是一種特殊的線性表,特殊之處在于它只允許在表的前端進行刪除操作,而在表的后端進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。

受這個隊列結構的啟發(fā),在前端不同的業(yè)務場景中,由于一次性發(fā)起的異步請求過多,并且這些服務位于不同組件或者不同兄弟功能之間,我們無法直接對這些方法進行同步,所以需要引入隊列的概念,對這些并發(fā)性的問題進行順序處理。

思考

為什么要寫一個類似于隊列的功能?

我們知道,在主流的V8引擎中,JavaScript 的執(zhí)行順序都是至上而下的,引入了 ajax 之后我們能夠對網頁進行局部刷新,在前端領域第一次有了異步操作的概念。自此,當我們接觸 Promise 之后也不在陌生于這種模式。當然,使用過 Promise 的都知道,如果是在某個單一的 js 文件中,我們完全可以通過編寫一個 async 函數,通過使用 await 去實現將 Promise 函數按順序執(zhí)行的功能。

那這個隊列小工具難道就是無意義的嗎?作者就像一個大渣男,玩弄了一番感情輕飄飄的走了?當然不是,大家都知道在單一文件中,我們總有辦法去實現這樣控制異步操作的功能,那么在不同的模塊、組件中,如何去實現這樣的操作呢?按照這個思路,我們可以發(fā)現單純的去寫是沒辦法直接解決這樣的異步功能同時觸發(fā)的問題的,這也就是作者為什么要去些一個類似于隊列的功能。

Promise 隊列功能的思路在哪里?

我們先要搞明白我們想要的是一個怎樣的功能呢?作者畫了一個大概的需要實現功能的流程圖,我們不同組件的異步請求是同時發(fā)生的,我們需要在發(fā)生之前把Promise 函數放入隊列工具,再讓隊列工具去調度出棧和入棧的順序,每次出棧的時候再去調用 Promise 函數發(fā)生請求。

我們可以在 js 文件中使用一個單例的概覽,主要是記錄入棧的順序和對操作加鎖,并且啟動一個定時服務去定期檢測棧中是否還有順序,思路是很簡單的,說干就干。

實現

我們新建一個 useQueue.js 文件,為了方便后續(xù)的引用。首先我們需要定義三個高級變量:

var queue = []
var locks = false
var timer = null
  • queue:記錄入棧的 Promise 任務函數
  • locks:在處理出棧任務時我們需要對函數加鎖,防止多次出棧
  • timer:防抖記錄,跟功能 locks 主要起一個保險左右,防止出棧時重復調用函數

我們定義兩個函數 handeruseQueue,導出默認函數 useQueue

/**
 * 處理任務出棧
 */
const hander = () => {}

/**
 * 入棧等待排隊操作
 * @param {Promise} task
 */
const useQueue = (task) => {}

/**
 * 導出
 */
export default useQueue

當我們有任務進入時,啟用 useQueue 函數,將任務放入棧中,并且設置 locks = true 進行解鎖。

const useQueue = (task) => {
  queue.push(task)
  locks = true
}

這個時候,我們在單例上設置一個心跳來定期檢測加鎖狀態(tài),如果是解鎖則觸發(fā)處理函數。

// 心跳
setInterval(() => {
  locks && handler()
}, 100)

當函數 hander 被成果觸發(fā),我們需要設置一個延時器來處理防抖。先進行加鎖,然后在隊列中進行出棧,如果出棧為空則解鎖;如果出棧不為空則調用任務,并且等待任務結束進入下一個 hander 。

const handler = () => {
  timer && clearTimeout(timer)
  timer = setTimeout(() => {
    locks = false
    const task = queue.shift()
    if (task) {
      task().then(handler)
    } else {
      locks = true
    }
  })
}

假設我們已經寫了一個 vue 字典標簽組件,組件內部會調用遠程接口,并且再記錄到某一個緩存中。如果一個頁面多次使用組件,而該緩存還并未存在,那么可能會導致同時觸發(fā)多個異步網絡請求。這個時候就可以使用隊列工具。

import useQueue from './useQueue.js'

const handleAjax = () => {
  return new Promise(resolve => {
    ...
    resolve()
  })
}

useQueue(handleAjax)

// 或者可以這樣調用
useQueue(async () => {
  await handleAjax()
})

總結

Promise 隊列工具實際上是通過延遲觸發(fā),來處理掛載在某一隊列數據上的出棧任務,原理其實并不復雜,就是為了處理異步請求同時發(fā)生的情況。當然,這個函數可以有更多的優(yōu)化方案,比如說可以添加一個優(yōu)先級的參數值,根據不同優(yōu)先級進行入棧操作,或者增加一個同類型排異等等。

到此這篇關于JavaScript實現一個Promise隊列小工具的文章就介紹到這了,更多相關JS Promise隊列內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

宜良县| 江达县| 铜山县| 炎陵县| 偃师市| 嘉祥县| 大厂| 白玉县| 正宁县| 永顺县| 沧源| 新泰市| 新丰县| 顺平县| 满洲里市| 安福县| 南华县| 安达市| 阿拉善右旗| 虎林市| 海口市| 高密市| 渭南市| 如皋市| 深水埗区| 万荣县| 广汉市| 郸城县| 马龙县| 故城县| 额尔古纳市| 罗山县| 高州市| 石阡县| 中超| 方山县| 鸡西市| 临湘市| 通城县| 双桥区| 双流县|