web-dev-qa-db-fra.com

Ma mise en œuvre de la demande Axios Debond a laissé la promesse en instance en attente pour toujours, est-ce une meilleure façon?

J'ai besoin d'une simple fonction de débond avec toujours réelle.
[.____] Sans recourir à Lodash et avec l'aide de Peut-on expliquer la fonction "DEBONCE" dans JavaScript , je l'ai mis en place comme suit,

function debounce(func, wait) {
    var timeout;
    return function() {
        if (!timeout) func.apply(this, arguments);
        clearTimeout(timeout);
        timeout = setTimeout(()=>{timeout = null}, wait);
    };
};

Cela fonctionne comme prévu jusqu'à ce que je dois débattre de la demande Axios. En supposé, j'ai une méthode Axios débondée, j'aimerais que la méthode d'appel soit aussi habituelle, ce qui signifie que ma méthode Axios débondis devrait revenir à la promesse, je crois.

   //the calling method should not change   
   debounced_axios().then(res => {...}).catch(err => {...}) 

L'essence de la mise en œuvre de l'abattage initial est de simplement exécuter Func une fois dans un calendrier d'attente, mais comment puis-je revenir un promets dans un calendrier d'attente?

Puis je suis venu avec la solution suivante

all_timers = {}
function debounce_axios(input, wait) {
    return new Promise((resolve, reject) => {
        let timer = all_timers.[input] //check if it is a repeated request, pseudo code
        if (!timer) {
            axios(input).then(res=>{
                resolve(res)
            }).catch(err => {
                reject(err)
            })
        }
        clearTimeout(timer);
        timer = setTimeout(()=>{timer = null}, wait);
        all_timers[input] = timer
    };
};

Donc, l'essence de mon debond_axios est de laisser la promesse rester dans l'état en attente de la demande répétée. Sort la méthode d'appel debounced_axios().then(res => {...}).catch(err => {...}) n'a pas besoin de changer.

La réponse ici sont javascript pour toujours-en attente de promesses ? dit "Il ne devrait y avoir aucun effet secondaire".

Mais je ne suis toujours pas sûr à 100% de laisser une promesse rester en attente pour toujours.

L'autre question est que promesses antidéterminations suggéré de ne pas créer de promesse inutile. Mais dans mon cas, créer une nouvelle promesse semble nécessaire.

En bref, il y a un moyen simple de débattre de la demande Axios (ou de toute demande de demande de demande)?

7
Qiulang

En substance, vous devez partager le résultat de votre fonction DEMONCE. Dans votre cas, c'est une promesse:

const debouncedGetData = debounce(getData, 500)
let promiseCount = 0
let resultCount = 0
test()

function test() {
  console.log('start')
  callDebouncedThreeTimes()
  setTimeout(callDebouncedThreeTimes, 200)
  setTimeout(callDebouncedThreeTimes, 900)
}

function callDebouncedThreeTimes () {
   for (let i=0; i<3; i++) {
      debouncedGetData().then(r => {
        console.log('Result count:', ++resultCount)
        console.log('r', r)
      })
   }
}

function debounce(func, wait) {
    let waiting;
    let sharedResult;
    return function() {
        // first call will create the promise|value here
        if (!waiting) {
          setTimeout(clearWait, wait)
          waiting = true
          sharedResult = func.apply(this, arguments);
        }
        // else new calls within waitTime will be discarded but shared the result from first call

        function clearWait() {
          waiting = null
          sharedResult = null
        }

        return sharedResult
    };
}

function getData () {
  console.log('Promise count:', ++promiseCount)
  return new Promise((resolve, reject) => {
    setTimeout(() => {
       resolve(666)
    }, 1000)
  })
}
1
Doğancan Arabacı