溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用JavaScript實現一個Promise隊列小工具

發布時間:2022-08-30 11:53:33 來源:億速云 閱讀:190 作者:iii 欄目:開發技術

這篇“怎么用JavaScript實現一個Promise隊列小工具”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么用JavaScript實現一個Promise隊列小工具”文章吧。

思考

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

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

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

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

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

怎么用JavaScript實現一個Promise隊列小工具

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

實現

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

var queue = []
var locks = false
var timer = null
  • queue:記錄入棧的 Promise 任務函數

  • locks:在處理出棧任務時我們需要對函數加鎖,防止多次出棧

  • timer:防抖記錄,跟功能 locks 主要起一個保險左右,防止出棧時重復調用函數

我們定義兩個函數 hander、useQueue,導出默認函數 useQueue。

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

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

/**
 * 導出
 */
export default useQueue

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

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

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

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

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

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

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

import useQueue from './useQueue.js'

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

useQueue(handleAjax)

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

以上就是關于“怎么用JavaScript實現一個Promise隊列小工具”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女