亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript使用Promise實現(xiàn)分批處理接口請求

 更新時間:2023年11月29日 10:18:34   作者:FE_C_P小麥  
當(dāng)我們在實際項目中遇到需要批量發(fā)起上百條接口請求怎么辦呢,本文就來為大家介紹一下JavaScript如何使用Promise實現(xiàn)分批處理接口請求,需要的小伙伴可以參考一下

前言

不知你項目中有沒有遇到過這樣的情況,反正我的實際工作項目中真的遇到了這種玩意,一個接口獲取一份列表,列表中的每一項都有一個屬性需要通過另一個請求來逐一賦值,然后就有了這份封裝

真的是很多功能都是被逼出來的

這份功能中要提醒一下:批量請求最關(guān)鍵的除了分批功能之外,適當(dāng)?shù)萌∠蝿?wù)和繼續(xù)任務(wù)也很重要,比如用戶到了這個頁面后,正在發(fā)起百條數(shù)據(jù)請求,但是這些批量請求還沒完全執(zhí)行完,用戶離開了這個頁面,此時就需要取消剩下正在發(fā)起的請求了,而且如果你像我的遇到的項目一樣,頁面還會被緩存,那么為了避免用戶回到這個頁面,所有請求又重新發(fā)起一遍的話,就需要實現(xiàn)繼續(xù)任務(wù)的功能,其實這個繼續(xù)任務(wù)比斷點(diǎn)續(xù)傳簡單多了,就是過濾到那些已經(jīng)賦值的數(shù)據(jù)項就行了

如果看我啰啰嗦嗦一堆爛東西沒看明白的話,就直接看下面的源碼吧

源碼

【注】:這里的 httpRequest 請根據(jù)自己項目而定,比如我的項目是uniapp,里面的http請求是 uni.request,若你的項目是 axios 或者 ajax,那就根據(jù)它們來對 BatchHttp 中的某些部分進(jìn)行相應(yīng)的修改

比如:其中的 cancelAll() 函數(shù),若你的 http 取消請求的方式不同,那么這里取消請求的功能就需要相應(yīng)的修改,若你使用的是 fetch 請求,那除了修改 cancelAll 功能之外,singleRequest 中收集請求任務(wù)的方式也要修改,因為 fetch 是不可取消的,需要借助 AbortController 來實現(xiàn)取消請求的功能,

提示一下,不管你用的是什么請求框架,你都可以自己二次封裝一個 request.js,功能就仿照 axios 這種,返回的對象中包含一個 abort() 函數(shù)即可,那么這份 BatchHttp 也就能適用啦

BatchHttp.js

// 注:這里的 httpRequest 請根據(jù)自己項目而定,比如我的項目是uniapp,里面的http請求是 uni.request,若你的項目是 axios 或者 ajax,那就根據(jù)它們來對 BatchHttp 中的某些部分
import httpRequest from './httpRequest.js'

/**
 * 批量請求封裝
 */
export class BatchHttp {

    /** 
     * 構(gòu)造函數(shù) 
     * @param {Object} http - http請求對象(該http請求攔截器里切勿帶有任何有關(guān)ui的功能,比如加載對話框、彈窗提示框之類),用于發(fā)起請求,該http請求對象必須滿足:返回一個包含取消請求函數(shù)的對象,因為在 this.cancelAll() 函數(shù)中會使用到
     * @param {string} [passFlagProp=null] - 用于識別是否忽略某些數(shù)據(jù)項的字段名(借此可實現(xiàn)“繼續(xù)上一次完成的批量請求”);如:passFlagProp='url' 時,在執(zhí)行 exec 時,會過濾掉 items['url'] 不為空的數(shù)據(jù),借此可以實現(xiàn)“繼續(xù)上一次完成的批量請求”,避免每次都重復(fù)所有請求
     */ 
    constructor(http=httpRequest, passFlagProp=null) {
        /** @private @type {Object[]} 請求任務(wù)數(shù)組 */
        this.resTasks = []
        /** @private @type {Object} uni.request對象 */
        this.http = http
        /** @private @type {boolean} 取消請求標(biāo)志 */
        this.canceled = false
        /** @private @type {string|null} 識別跳過數(shù)據(jù)的屬性 */
        this.passFlagProp = passFlagProp
    }


    /**
     * 將數(shù)組拆分成多個 size 長度的小數(shù)組
     * 常用于批量處理控制并發(fā)等場景
     * @param {Array} array - 需要拆分的數(shù)組
     * @param {number} size - 每個小數(shù)組的長度
     * @returns {Array} - 拆分后的小數(shù)組組成的二維數(shù)組
    */
    #chunk(array, size) {
        const chunks = []
        let index = 0
    
        while(index < array.length) {
        chunks.push(array.slice(index, size + index))
        index += size;
        }
    
        return chunks
    }

    /** 
     * 單個數(shù)據(jù)項請求 
     * @private
     * @param {Object} reqOptions - 請求配置
     * @param {Object} item - 數(shù)據(jù)項 
     * @returns {Promise} 請求Promise
    */
    #singleRequest(reqOptions, item) {
        return new Promise((resolve, _reject) => {
            const task = this.http({
                url: reqOptions.url, 
                method: reqOptions.method || 'GET',
                data: reqOptions.data,
                success: res => {
                    resolve({sourceItem:item, res})
                }
            })
            this.resTasks.push(task)
        })
    }

    /**
     * 批量請求控制
     * @private
     * @async
     * @param {Object} options - 函數(shù)參數(shù)項
     * @param {Array} options.items - 數(shù)據(jù)項數(shù)組
     * @param {Object} options.reqOptions - 請求配置  
     * @param {number} [options.concurrentNum=10] - 并發(fā)數(shù)
     * @param {Function} [options.chunkCallback] - 分塊回調(diào) 
     * @returns {Promise}
    */
    async #batchRequest({items, reqOptions, concurrentNum = 10, chunkCallback=(ress)=>{}}) {
        const promiseArray = []
        let data = []
        const passFlagProp = this.passFlagProp
        if(!passFlagProp) {
            data = items
        } else {
            // 若設(shè)置獨(dú)立 passFlagProp 值,則篩選出對應(yīng)屬性值為空的數(shù)據(jù)(避免每次都重復(fù)請求所有數(shù)據(jù),實現(xiàn)“繼續(xù)未完成的批量請求任務(wù)”)
            data = items.filter(d => !Object.hasOwnProperty.call(d, passFlagProp) || !d[passFlagProp])
        }
        // --
        if(data.length === 0) return

        data.forEach(item => {
            const requestPromise = this.#singleRequest(reqOptions, item)
            promiseArray.push(requestPromise)
        })

        const promiseChunks = this.#chunk(promiseArray, concurrentNum) // 切分成 n 個請求為一組

        for (let ck of promiseChunks) {
            // 若當(dāng)前處于取消請求狀態(tài),則直接跳出
            if(this.canceled) break
            // 發(fā)起一組請求
            const ckRess = await Promise.all(ck) // 控制并發(fā)數(shù)
            chunkCallback(ckRess) // 每完成組請求,都進(jìn)行回調(diào)
        }
    }

    /**
     * 設(shè)置用于識別忽略數(shù)據(jù)項的字段名
     * (借此參數(shù)可實現(xiàn)“繼續(xù)上一次完成的批量請求”);
     * 如:passFlagProp='url' 時,在執(zhí)行 exec 時,會過濾掉 items['url'] 不為空的數(shù)據(jù),借此可以實現(xiàn)“繼續(xù)上一次完成的批量請求”,避免每次都重復(fù)所有請求
     * @param {string} val 
     */
    setPassFlagProp(val) {
        this.passFlagProp = val
    }

    /**
     * 執(zhí)行批量請求操作
     * @param {Object} options - 函數(shù)參數(shù)項
     * @param {Array} options.items - 數(shù)據(jù)項數(shù)組
     * @param {Object} options.reqOptions - 請求配置  
     * @param {number} [options.concurrentNum=10] - 并發(fā)數(shù)
     * @param {Function} [options.chunkCallback] - 分塊回調(diào) 
     */
    exec(options) {
        this.canceled = false
        this.#batchRequest(options)
    }

    /**
     * 取消所有請求任務(wù)
     */
    cancelAll() {
        this.canceled = true
        for(const task of this.resTasks) {
            task.abort()
        }
        this.resTasks = []
    }
}

到此這篇關(guān)于JavaScript使用Promise實現(xiàn)分批處理接口請求的文章就介紹到這了,更多相關(guān)JavaScript Promise分批處理請求內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • javascript插入樣式實現(xiàn)代碼

    javascript插入樣式實現(xiàn)代碼

    最近做一個項目,需要javascript動態(tài)插入樣式,結(jié)果以前的方法失效了!查了2個小時的原因竟然是自己手賤,這個最后再說
    2012-02-02
  • JS實現(xiàn)拖動模態(tài)框案例

    JS實現(xiàn)拖動模態(tài)框案例

    這篇文章主要為大家詳細(xì)介紹了JS實現(xiàn)拖動模態(tài)框案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 微信小程序?qū)崿F(xiàn)事件傳參與數(shù)據(jù)同步流程詳解

    微信小程序?qū)崿F(xiàn)事件傳參與數(shù)據(jù)同步流程詳解

    這篇文章主要介紹了微信小程序開發(fā)中實現(xiàn)事件傳參與數(shù)據(jù)同步的詳細(xì)流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • JavaScript對象屬性檢查、增加、刪除、訪問操作實例

    JavaScript對象屬性檢查、增加、刪除、訪問操作實例

    這篇文章主要介紹了JavaScript對象屬性檢查、增加、刪除、訪問操作實例,本文分別給出代碼實例來講解如何給對象增加屬性、檢查屬性存在、以及刪除和訪問屬性,需要的朋友可以參考下
    2015-07-07
  • JavaScript實現(xiàn)鼠標(biāo)經(jīng)過表格某行時此行變色

    JavaScript實現(xiàn)鼠標(biāo)經(jīng)過表格某行時此行變色

    這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)鼠標(biāo)經(jīng)過表格某行時此行變色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Java?@Schema和@ApiModel等注解的聯(lián)系淺析

    Java?@Schema和@ApiModel等注解的聯(lián)系淺析

    這篇文章主要給大家介紹了關(guān)于Java?@Schema和@ApiModel等注解的聯(lián)系的相關(guān)資料,我在看公司之前的文檔,發(fā)現(xiàn)了@schema注解,不太了解,所以查詢了一些資料,把我的見解記錄下,需要的朋友可以參考下
    2023-08-08
  • 基于javascript實現(xiàn)判斷移動終端瀏覽器版本信息

    基于javascript實現(xiàn)判斷移動終端瀏覽器版本信息

    這篇文章主要介紹了基于javascript實現(xiàn)判斷移動終端瀏覽器版本信息,需要的朋友可以參考下
    2014-12-12
  • TypeScript中的類型運(yùn)算符實現(xiàn)

    TypeScript中的類型運(yùn)算符實現(xiàn)

    TypeScript 是一種強(qiáng)類型語言,它通過使用類型運(yùn)算符來強(qiáng)化類型安全性,本文主要介紹了TypeScript中的類型運(yùn)算符實現(xiàn),感興趣的可以了解一下
    2023-10-10
  • 基于ajax和jsonp的原生封裝(實例)

    基于ajax和jsonp的原生封裝(實例)

    下面小編就為大家?guī)硪黄赼jax和jsonp的原生封裝(實例)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • JS簡單實現(xiàn)移動端日歷功能示例

    JS簡單實現(xiàn)移動端日歷功能示例

    這篇文章主要介紹了JS簡單實現(xiàn)移動端日歷功能的方法,涉及javascript針對日期與時間的操作及顯示相關(guān)技巧,需要的朋友可以參考下
    2016-12-12

最新評論