Axios e Vue3: limitare il numero di richieste

Ho creato un uploader con Vue3 e Axios per caricare dei files tramite backend Laravel + Spatie Medialibrary.
La parte di script che si occupa dell'upload è una semplice richiesta POST:

axios.post(
    route("media.store"),
    formData,
)
.then(function (response) {
.......
.......
.......


Tutto funzionante ma selezionando tanti files in una volta il server iniziava a "soffrire", specialmente in caso di immagini che dovevano poi essere elaborate.

La soluzione quindi è quella di limitare il numero di richieste concorrenti direttamente dal frontend.
Ho trovato alcune librerie da installare tramite npm ma non volevo qualcosa di pesante e con mille opzioni.
Cercando un po' in giro ho trovato un ottimo script di Mattew Suan a questo link: https://gist.github.com/matthewsuan/2bdc9e7f459d5b073d58d1ebc0613169

Riporto qui il codice in cui io ho impostato come limite 2 request concorrenti:

import axios from "axios";

const MAX_REQUESTS_COUNT = 2;
const INTERVAL_MS = 1000;
let PENDING_REQUESTS = 0;

// create new axios instance
const api = axios.create({});

/**
 * Axios Request Interceptor
 */
api.interceptors.request.use(function (config) {
    return new Promise((resolve, reject) => {
        let interval = setInterval(() => {
            if (PENDING_REQUESTS < MAX_REQUESTS_COUNT) {
                PENDING_REQUESTS++;
                clearInterval(interval);
                resolve(config);
            }
        }, INTERVAL_MS);
    });
});

/**
 * Axios Response Interceptor
 */
api.interceptors.response.use(
    function (response) {
        PENDING_REQUESTS = Math.max(0, PENDING_REQUESTS - 1);
        return Promise.resolve(response);
    },
    function (error) {
        PENDING_REQUESTS = Math.max(0, PENDING_REQUESTS - 1);
        return Promise.reject(error);
    }
);

export default api;

E come si usa?
Molto semplice: come prima cosa ho creato un file che ho chiamato axiosLimit.js (nella directory resources/js/Plugins) con il codice qui sopra.

Nel mio component ho sostituito

import axios from "axios";

con

import axiosLimit from "@/Plugins/axiosLimit.js";

A questo punto è sufficiente sostituire "axios" con "axiosLimit" nel codice e lo script funziona limitando il numero di files caricati contemporaneamente:

axiosLimit.post(
    route("media.store"),
    formData,
)
.then(function (response) {

Ovviamente nel caso in cui in un componente ci siano anche altre richieste al server (ad esempio per cancellare i dati o modificarli) è possibile usare axios o axiosLimit in base alle necessità.


Commenti