Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

200
Visualizações
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 à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda