Search code examples
javascripttypescriptasynchronousasync-awaitlodash

lodash groupBy is a long sync operation starving all other async operations


I'm using lodash group by on a large array, The operation takes a few minutes, which is starving all other async promisees (since we aren't releasing the context)

Does anyone have suggestions to use a different lib \ modify my use of groupBy to solve this?


Solution

  • Sonce groupBy is just

    function groupBy<T, V extends PropertyKey>(
      list: T[], get: (v:T) => V,
    ): Record<V, T[]> {
      const r = {} as Record<V, T[]>
      for (const el of list) {
        (r[get(el)] ??= []).push(el)
      }
      return r
    }
    

    you may easily add an interceptor to wait if it takes too long:

    async function groupBy<T, V extends PropertyKey>(
      list: T[], get: (v:T) => V,
    ): Record<V, T[]> {
      const r = {} as Record<V, T[]>
      let now = performance.now()
      for (const el of list) {
        // if `get` is fast, better to smth like `if (i%100==0)` here
        if (performance.now() - now > 10 /*ms*/) {
          // break the execution
          await new Promise(setTimeout) // or whatever waiting function
          now = performance.now()
        }
        (r[get(el)] ??= []).push(el)
      }
      return r
    }