Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Last active February 27, 2020 22:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gvergnaud/29b3520f8a176904313ff935434bf683 to your computer and use it in GitHub Desktop.
Save gvergnaud/29b3520f8a176904313ff935434bf683 to your computer and use it in GitHub Desktop.
A `batch` function to batch several IOs together to gain in performance with the same api as if you were doing one IO at a time.
import { debounce } from 'lodash';
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}
}
// just like debounce but returns a promise that resolves with the returned value of `f`
// debouncePromise :: (a -> Promise b) -> Number -> a -> Promise b
const debouncePromise = (f, ms) => {
let deferreds = [];
const debounced = debounce(args => {
const x = f(...args);
for (const deferred of deferreds) deferred.resolve(x);
deferreds = [];
}, ms);
return (...args) => {
const deferred = new Deferred();
deferreds.push(deferred);
debounced(args);
return deferred.promise;
};
};
// batch
// :: ([a] -> b)
// -> Number?
// -> [a]
// -> Promise b
export const batch = (f, ms = 50) => {
let argumentsSet = new Set();
const debounced = debouncePromise(() => {
const list = [...argumentsSet];
argumentsSet.clear();
return f(list);
}, ms);
return xs => {
for (const x of xs) argumentsSet.add(x);
return debounced();
};
};
import { batch } from './batch'
const getSeveralUsers = batch(userIds =>
fetch(`${someApi}/users?ids=${usersIds.join(',')}`).then(res => res.json())
)
const getUser = id => getSeveralUsers([id]).then(users => users.find(u => u.id === id))
// all this calls will be batched into one!
getUser(1).then(user1 => console.log(user1))
getUser(2)
getUser(3)
getUser(4)
getUser(5)
getUser(6)
// => it will result in a single getSeveralUsers([1, 2, 3, 4, 5, 6]) function call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment