summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/lib/utils/ignore_while_pending.js
blob: e85a573c8f23ba1afe3bf14b39b51e44e0087461 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * This will wrap the given function to make sure that it is only triggered once
 * while executing asynchronously
 *
 * @param {Function} fn some function that returns a promise
 * @returns A function that will only be triggered *once* while the promise is executing
 */
export const ignoreWhilePending = (fn) => {
  const isPendingMap = new WeakMap();
  const defaultContext = {};

  // We need this to be a function so we get the `this`
  return function ignoreWhilePendingInner(...args) {
    const context = this || defaultContext;

    if (isPendingMap.get(context)) {
      return Promise.resolve();
    }

    isPendingMap.set(context, true);

    return fn.apply(this, args).finally(() => {
      isPendingMap.delete(context);
    });
  };
};