Introduction
Dans ce laboratoire, nous allons explorer comment créer une fonction anti-basculement qui renvoie une promesse en JavaScript. Nous apprendrons à différer l'appel d'une fonction jusqu'à ce qu'un temps spécifié soit écoulé, et à gérer les multiples promesses renvoyées pendant ce temps pour vous assurer qu'elles renvoient toutes les mêmes données. À la fin de ce laboratoire, vous aurez une compréhension solide de la manière d'implémenter l'anti-basculement avec des promesses dans vos projets JavaScript.
Debounce Promise
Pour créer une fonction anti-basculement qui renvoie une promesse, en différant l'appel de la fonction fournie jusqu'à ce qu'au moins ms millisecondes se soient écoulées depuis la dernière fois qu'elle a été appelée, utilisez les étapes suivantes :
- Chaque fois que la fonction anti-basculement est appelée, annulez le délai en attente actuel avec
clearTimeout(), puis utilisezsetTimeout()pour créer un nouveau délai qui différera l'appel de la fonction jusqu'à ce qu'au moinsmsmillisecondes se soient écoulées. - Utilisez
Function.prototype.apply()pour appliquer le contextethisà la fonction et fournir les arguments nécessaires. - Créez une nouvelle
Promiseet ajoutez ses callbacksresolveetrejectà la pile des promesses en attente. - Lorsque
setTimeout()est appelé, copiez la pile actuelle (car elle peut changer entre l'appel de la fonction fournie et sa résolution), videz-la et appelez la fonction fournie. - Lorsque la fonction fournie se résout/rejette, résolvez/rejetez toutes les promesses de la pile (copiée lors de l'appel de la fonction) avec les données renvoyées.
- Omettez le second argument,
ms, pour définir le délai à la valeur par défaut de0ms.
Voici le code pour la fonction debouncePromise() :
const debouncePromise = (fn, ms = 0) => {
let timeoutId;
const pending = [];
return (...args) =>
new Promise((res, rej) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
const currentPending = [...pending];
pending.length = 0;
Promise.resolve(fn.apply(this, args)).then(
(data) => {
currentPending.forEach(({ resolve }) => resolve(data));
},
(error) => {
currentPending.forEach(({ reject }) => reject(error));
}
);
}, ms);
pending.push({ resolve: res, reject: rej });
});
};
Voici un exemple d'utilisation de debouncePromise() :
const fn = (arg) =>
new Promise((resolve) => {
setTimeout(resolve, 1000, ["resolved", arg]);
});
const debounced = debouncePromise(fn, 200);
debounced("foo").then(console.log);
debounced("bar").then(console.log);
// Affichera ['resolved', 'bar'] les deux fois
Résumé
Félicitations ! Vous avez terminé le laboratoire Debounce Promise. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.