Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

194
Vistas
abstract base class with async methods that can sometimes be sync

tl;dr - how to make a version of a class that has all its async methods replace by sync ones? (or visa versa)

Background info:

I have created an abstract base class using symbols, something like this:

  const sProtectedMethod = Symbol();
  class AbstractBase() {
    constructor() {
      if (new.target === AbstractBase) {
        throw new TypeError(`AbstractBase is abstract and cannot be instantiated directly. Use a derived class`);
      }
    }
    async #protectedMethod() { // this is just a convience to avoid the ugly symbol syntax everytime we call the function
      await this[sProtectedMethod]();
    }
    async publicMethod() {
      await longAndComplexFunctionCallChainThatEventuallyAwaitsProtectedMethodButDoesntAwaitAnythingElse();

  }

where the derived classes look like this:

  class Derived extends AbstractBase {
    async [sProtectedMethod]() {
      // implementation here
    }

So far so good. But - in some derived classes the implementation of the overriden method must be async (because it does I/O or whatever) while in other implementations this method could be synchronus. I did an experiment to see if making the method synchronus would be faster and it is - approx. 1000x faster.

I could make 2 versions of the AbstractBase - a sync and an async version. But here's the catch - the protectedMethod is actually called many times, pretty deep into a long chain of functions - all of which must be async if the overriden implementation is also async.

So rather than maintain 2 versions of the class that are almost identical, I'd like a way to automatically create a sync version from an async version, or visa versa.

I have managed this with a string replace and an eval

const AbstractBaseSync = eval(`${AbstractBase.toString().replace(/async|await/g, ``)}; AbstractBase`);

But even though I think this is safe (providing there are no strings within the class that contain the words async or await), the use of eval and I'm hoping there is a better way.

Also, although it seems to work in Chrome, Firefox + Node - I know implementations of toString may differ, which might cause issues later.

If I dispensed with the #private members and used _convention instead, then maybe I could do it member by member with reflection, but I don't think it would be much better as eval or new Function(...) would still be required.

What is the cleanest way to do this?

about 4 years ago · Juan Pablo Isaza
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda