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

326
Vistas
Pregunta de entrevista de codificación de manejo de concurrencia de Node JS

Asistí a una entrevista de codificación de NodeJS. Obtuve el siguiente código que se ejecuta de forma asíncrona desde diferentes navegadores (se supone). Nuestra solución necesita bloquear la ejecución de la función si la actualización por ID es la misma pero se llama desde un lugar diferente (por ejemplo, navegador). Y luego suelte el bloqueo para la ejecución de la siguiente solicitud.

Aquí no se deben realizar cambios para el código mencionado a continuación.

 async function update(id, data) { console.log(`start --> id:${id}, data:${data}`); await randomDelay(); //update is happening here console.log(`end --> id:${id}, data:${data}`); } //============================================================================= //================= Don't change anything below =============================== //============================================================================= //---- update() is getting called from many places ---- update(1, "browser 1"); update(1, "browser 2"); //========================= Utility functions =================================== //========================= Don't change any here================================ async function sleep(ms) { return new Promise((resolve, reject) => { setTimeout(() => resolve(), ms); }); } async function randomDelay() { const randomTime = Math.round(Math.random() * 1000); return sleep(randomTime); }

Esto dará una salida como la siguiente.

 start --> id:1, data:browser 1 start --> id:1, data:browser 2 end --> id:1, data:browser 1 end --> id:1, data:browser 2

La respuesta esperada es

 start --> id:1, data:browser 1 end --> id:1, data:browser 1 start --> id:1, data:browser 2 end --> id:1, data:browser 2

Tenga en cuenta los comentarios en el código "No cambie nada a continuación". ¿Cuál sería la posible solución?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Puede usar una tabla hash de colas codificada por ID para que solo los trabajos con la misma ID se ejecuten consecutivamente, de lo contrario, se ejecutan simultáneamente.

 let hash = {}; class Queue { constructor() { this.isBusy = false; this.jobs = []; } push(jobFn) { return new Promise((resolve) => { this.jobs.push({ jobFn, resolve }); this.next(); }); } next() { if (this.isBusy || this.jobs.length === 0) return; this.isBusy = true; let currJob = this.jobs.shift(); return currJob.jobFn().then((data) => { currJob.resolve(data); this.isBusy = false; this.next(); }); } } async function update(id, data) { const updateFn = async () => { console.log(`start --> id:${id}, data:${data}`); await randomDelay(); //update is happening here console.log(`end --> id:${id}, data:${data}`); }; if (id in hash) { hash[id].push(updateFn); } else { hash[id] = new Queue(updateFn); hash[id].push(updateFn); } } //============================================================================= //================= Don't change anything below =============================== //============================================================================= //---- update() is getting called from many places ---- update(1, "browser 1"); update(1, "browser 2"); update(2, "browser 1"); update(2, "browser 2"); update(1, "browser 3"); update(1, "browser 4"); //========================= Utility functions =================================== //========================= Don't change any here================================ async function sleep(ms) { return new Promise((resolve, reject) => { setTimeout(() => resolve(), ms); }); } async function randomDelay() { const randomTime = Math.round(Math.random() * 1000); return sleep(randomTime); }

about 4 years ago · Juan Pablo Isaza Denunciar

0

Esta solución funciona solo para two llamadas de consecuencia con datos diferentes a los esperados, por lo que estoy trabajando para ampliarla, pero por ahora, espero que les dé una buena visión de cómo debería implementarse.

 const callStack = [] async function update(id, data) { const stackLen = callStack.length; let currentIndex; if (stackLen) { let currentCall = callStack[stackLen - 1]; if (currentCall.start == true && currentCall.await == true) { setImmediate(() => update(id, data)) return; } currentIndex = stackLen - 1; if (currentCall.args[0] == id && currentCall.args[1] !== data) { if (currentCall.await === true) { currentCall.start = true; update(id, data) return; } } } else { callStack.push({ args: [...arguments], await: true }) currentIndex = 0; } console.log(`start --> id:${id}, data:${data}`); await randomDelay(); //update is happening here console.log(`end --> id:${id}, data:${data}`); callStack[currentIndex].await = false; }
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