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

227
Visualizações
¿Cómo puedo encadenar funciones de forma asíncrona usando JavaScript?

Me pidieron que creara un objeto llamado foo que pudiera encadenar el log funciones y wait .

Por ejemplo:

 foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner');

En este escenario, primero imprime el breakfast , espera 3 segundos, imprime el lunch y luego, después de 3 segundos, imprime la dinner .

Intenté algo como esto, pero no funciona. ¿Qué me perdí?

 var foo = { log: function(text){ console.log(text); return foo; }, wait: function(time) { setTimeout(function() { return foo; }, time); } } foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner');

over 4 years ago · Santiago Trujillo
6 Respostas
Responde à pergunta

0

Puedes hacerlo sin promesas:

 const foo = { log(text) { return {...foo, start: () => { this.start(); console.log(text); }}; }, wait(time) { return {...foo, start: () => { setTimeout(this.start, time); }}; }, start() {} }; foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner').start();
Las funciones foo.log() y foo.wait() regresan inmediatamente, devolviendo un clon modificado de foo . Se crea un clon usando {...foo} , pero con la función start() modificada para que llame a this.start() de la persona que llama seguido de la nueva operación. Cuando la cadena está completa, llama a start() para iniciar las acciones.

over 4 years ago · Santiago Trujillo Relatório

0

Siempre es mejor usar promesas. Una implementación de esta funcionalidad podría ser;

 class Foo { constructor(){ this.promise = Promise.resolve(); } log(txt){ this.promise = this.promise.then(_ => console.log(txt)) return this; } wait(ms){ this.promise = this.promise.then(_ => new Promise(v => setTimeout(v,ms))); return this; } } var foo = new Foo(); foo.log("happy").wait(1000).log("new").wait(1000).log("year");

over 4 years ago · Santiago Trujillo Relatório

0

Coloque la llamada a wait dentro de la anterior, y como último elemento, como una función recursiva.

 meals=['breakfast','elevenses','lunch','afternoon tea','dinner','supper']; c=0; wait=t=>{setTimeout(function() { if (c<meals.length) document.write(meals[c++],'<br>');wait(500); }, t);} wait(500);

over 4 years ago · Santiago Trujillo Relatório

0

Para que conste, la excelente respuesta de Redu sin el azúcar de clase .

Ver también

 const foo = { promise: Promise.resolve(), log(txt) { this.promise.then(_ => console.log(txt)); return this; }, wait(ms) { this.promise = this.promise.then(_ => new Promise(v => setTimeout(v, ms))); return this; } }; // OR const Foo = (defaultMs = 1000) => { let promised = Promise.resolve(); return { log(txt) { promised.then(_ => console.log(txt)); return this; }, wait: function(ms) { promised = promised.then( _=> new Promise( rs => setTimeout(rs, ms || defaultMs) ) ); return this; } }; }; foo.log("Happy").wait(1000).log("new").wait(1000).log("year"); Foo().wait(3000) .log(`** From Foo ;)`).log(`Happy`).wait().log("new").wait().log("year");

over 4 years ago · Santiago Trujillo Relatório

0

Más corto, dentro de Promise (no recomendado).

 Promise.prototype.log = function(txt) { return this.then(() => console.log(txt)) } Promise.prototype.wait = function(ms) { return this.then(() => new Promise(res => setTimeout(res, ms))) } var foo = Promise.resolve() foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner')
over 4 years ago · Santiago Trujillo Relatório

0

Me inspiré en la solución de @James, que es parcialmente incorrecta porque los mensajes de registro están en el orden inverso, pero él no usa Promise s. Sigo pensando que la solución de @Redu debería ser la aceptada (después de todo, si puedes usar Promise s, eso es perfecto), pero esta también es interesante en mi opinión:

 const foo1 = { incrementalTimeout: 0, nextActions: [], log(text) { const textLog = () => { console.log(text); }; if (this.incrementalTimeout == 0) textLog(); else this.nextActions.push(textLog); return this; }, wait(time) { let newObj = {...this, incrementalTimeout: this.incrementalTimeout + time, nextActions: []}; setTimeout(() => { newObj.nextActions.forEach((action) => action()); } , newObj.incrementalTimeout); return newObj; } } foo1.log('breakfast').wait(1000).log('lunch').wait(3000).log('dinner');

La idea es que no registre el text de inmediato, sino que push una lambda con console.log en una matriz que se llamará después de que expire el tiempo de espera correcto.

Ejecuto todas las operaciones de log y wait una tras otra, pero llevo un registro de los segundos de espera antes de ejecutar las acciones. Cada vez que se llama a una nueva wait , el tiempo de espera incrementalTimeout se incrementa en time . Para mantener separadas las nextActions que pertenecen a diferentes períodos de tiempo, devuelvo un newObj cada vez, más o menos como lo hace @James.

over 4 years ago · Santiago Trujillo Relatório
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