Update and rename promiseDebounce.md to debouncePromise.md

This commit is contained in:
Angelos Chalaris
2020-10-10 21:09:04 +03:00
committed by GitHub
parent e5bf945d95
commit 02429b250a

View File

@ -1,49 +1,48 @@
--- ---
title: promiseDebounce title: debouncePromise
tags: promise,debounce,intermediate tags: function,promise,advanced
--- ---
Creates a debounced function that returns a promise, but delays invoking the provided function until at least `ms` milliseconds have elapsed since the last time it was invoked. All promises returned during this time will return the same data. Creates a debounced function that returns a promise, but delays invoking the provided function until at least `ms` milliseconds have elapsed since the last time it was invoked.
All promises returned during this time will return the same data.
- Each time the debounced function is invoked, clear the current pending timeout with `clearTimeout()` and use `setTimeout()` to create a new timeout that delays invoking the function until at least `ms` milliseconds has elapsed. - Each time the debounced function is invoked, clear the current pending timeout with `clearTimeout()` and use `setTimeout()` to create a new timeout that delays invoking the function until at least `ms` milliseconds has elapsed.
- create a new `Promise` and add it's `resolve` and `reject` callback to pending promises stack.
- When `setTimeout` is called: copy current stack (as it can change between provided function call and resolve), clear it and call provided function.
- When provided function resolves/rejects, finish all promises from stack (copied when function was called) with returned data.
- Use `Function.prototype.apply()` to apply the `this` context to the function and provide the necessary arguments. - Use `Function.prototype.apply()` to apply the `this` context to the function and provide the necessary arguments.
- Create a new `Promise` and add its `resolve` and `reject` callbacks to the `pending` promises stack.
- When `setTimeout` is called, copy the current stack (as it can change between the provided function call and its resolution), clear it and call the provided function.
- When the provided function resolves/rejects, resolve/reject all promises in the stack (copied when the function was called) with the returned data.
- Omit the second argument, `ms`, to set the timeout at a default of 0 ms. - Omit the second argument, `ms`, to set the timeout at a default of 0 ms.
```js ```js
const promiseDebounce = (fn, ms = 0) => const debouncePromise = (fn, ms = 0) => {
{ let timeoutId;
let timeoutId; const pending = [];
const pending = []; return (...args) =>
new Promise((res, rej) => {
return (...args) => new Promise((res, rej) => {
clearTimeout(timeoutId); clearTimeout(timeoutId);
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
const currentPending = [...pending]; const currentPending = [...pending];
pending.lenght = 0; pending.length = 0;
Promise.resolve(fn.apply(this, args)).then( Promise.resolve(fn.apply(this, args)).then(
data => { data => {
currentPending.forEach(({ resolve }) => resolve(data)); currentPending.forEach(({ resolve }) => resolve(data));
}, },
error => { error => {
currentPending.forEach(({ reject }) => reject(error)); currentPending.forEach(({ reject }) => reject(error));
}, }
) );
}, ms); }, ms);
pending.push({ resolve: res, reject: rej }); pending.push({ resolve: res, reject: rej });
}); });
} };
``` ```
```js ```js
//some function returning promise
const fn = arg => new Promise(resolve => { const fn = arg => new Promise(resolve => {
setTimeout(resolve, 1000, ['resolved', arg]); setTimeout(resolve, 1000, ['resolved', arg]);
}); });
const debounced = promiseDebounce(fn, 200); const debounced = debouncePromise(fn, 200);
debounced('foo').then(console.log); debounced('foo').then(console.log);
debounced('bar').then(console.log); debounced('bar').then(console.log);
// will log ['resolved', 'bar'] both times. // Will log ['resolved', 'bar'] both times
``` ```