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

154
Vistas
Override function prototype with async method, keeping this context

In javascript if i have a function defined like so

function Person() {
}

Person.prototype.someFunction = function() {
  // Does soome logic
  return this
}

Person.prototype.anotherFunction = function () {
  // Does soome logic
  return this;
};


And i want to implement chaining i will do something like this

const person = new Person();

person.someFunction().anotherFunction()

And this works as each method returns the instance of Person.

Now if i have a method which has some async action how do i return the this instsance in an async method

function someApiCall() {
  return new Promise((res) => {
    setTimeout(() => {
      res('got data');
    }, 2000);
  });
}


Person.prototype.asyncFunction = function () {
  someApiCall()
    .then()
    .catch()

  // HOW DO I RETURN THIS INSTANCE HERE ???? as someAPICALL is async
};

So that i can use it as

person.someFunction().asyncFunction().anotherFunction()
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Option 1 (Not executed in order):

Person.prototype.asyncFunction1 = function () {
  someApiCall()
  .then((e) => console.log(e))
  .catch()

  return this;
};

p.anotherFunction().asyncFunction1().anotherFunction()

All functions get called, but not in order. If you want to execute it in order, just do it like this:

Option 2 (Executed in order):

Person.prototype.asyncFunction2 = async function () {
  const ans = await someApiCall();
  console.log(ans);
  return this;
};

// t represents this as you return it in asyncFunction2 
p.anotherFunction().asyncFunction2().then((t) => t.anotherFunction())
about 4 years ago · Juan Pablo Isaza Denunciar

0

You're trying to apply a synchronous programming paradigm to an asynchronous code approach, and that's just not going to work. When working with promises, which is what async does for you in an automatic way, rather than instance chaining, your code logic now needs to deal with promise chaining instead.

First, let's stop using legacy prototype syntax and look at modern (where "modern" is over five years old by now) class syntax:

class Person {
  async someFunction() {
    return ...
  }

  async anotherFunction() {
    return ...
  }
}

Because async is just a convenient promise wrapping, we have two options:

const person = new Person();
person
  .someFunction()
  .then(result => {
    person
      .anotherFunction()
      .then(result => ...);
      .catch(e => console.error(e));
  })
  .catch(e => console.error(e));

but this is both cumbersome and ugly. Let's use awaits instead:

const person = new Person();
try {
  const someResult = await person.someFunction();
  const anotherResult = await person..anotherFunction();
  ...
} catch (e) {
  console.error(e);
}

Much better. We don't need instance chaining anymore when we're using async patterns, it's a pattern from a previous era of JS, and writing modern code does not benefit from trying to force it back in.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Some people are telling you that it can never be done or it's just not going to work. It's not their fault for misunderstanding but you don't need to suffer the same way as them.

Let' say you have an ordinary class, Account, with a few async methods -

class Account {
  constructor(balance) {
    this.balance = balance
  }
  async withdraw (x) {
    await sleep(1000)
    this.balance -= x
  }
  async deposit (x) {
    await sleep(1000)
    this.balance += x
  }
}

sleep is a simple function which delays the program for ms milliseconds -

const sleep = ms =>
  new Promise(r => setTimeout(r, ms))

Now we can write a chain function -

const chain = t =>
 new Proxy(Promise.resolve(t), { get: get(t) })

const get = t => (target, prop) => (...args) => 
  prop === "then"
    ? target[prop](...args)
    : chain(target.then(async v => (await v[prop](...args), v)))

This seemingly allows us to mix synchronous and asynchronous behaviour -

const A = new Account(100)
const B = new Account(200)

chain(A).deposit(5).withdraw(20).then(a => console.log("A", a))
chain(B).withdraw(20).withdraw(30).deposit(10).then(b => console.log("B", b))

Run the snippet below to verify the result in your own browser -

const sleep = ms =>
  new Promise(r => setTimeout(r, ms))

const get = t => (target, prop) => (...args) => 
  prop === "then"
    ? target[prop](...args)
    : chain(target.then(async v => (await v[prop](...args), v)))

const chain = t =>
 new Proxy(Promise.resolve(t), { get: get(t) })
  
class Account {
  constructor(balance) {
    this.balance = balance
  }
  async withdraw (x) {
    await sleep(1000)
    this.balance -= x
  }
  async deposit (x) {
    await sleep(1000)
    this.balance += x
  }
}

const A = new Account(100)
const B = new Account(200)

chain(A).deposit(5).withdraw(20).then(a => console.log("A", a))
chain(B).withdraw(20).withdraw(30).deposit(10).then(b => console.log("B", b))
console.log("running...")

A { balance: 85 }
B { balance: 160 }

Invent your own convenience. It's your program to do with as you please.

about 4 years ago · Juan Pablo Isaza Denunciar
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