Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

170
Views
¿Por qué JS redis se repite más veces después de una escritura exitosa?

Tengo la siguiente lógica para leer y escribir el estado de redis

 export async function updateRedis() { let stateName = 'stateName' try { let isSuccess = false while (!isSuccess) { try { await redis .watch(stateName, function (err) { if (err) { logger.error(`Error in watch state: ${err}`) } redis.get(stateName, function (err, result) { if (err) { logger.error(`Error in get state: ${err}`) } let state = JSON.parse(result) // do some processing redis.multi() .set(stateName, JSON.stringify(state)) .exec(function (err, result) { if (err) { logger.error(`Error in set state: ${err}`) } if (result != null) { isSuccess = true } }) console.log(`isSuccess for ${stateName} `, isSuccess) }) }) } catch (e) { logger.error(`Error: ${e}`) } } } catch (e) { logger.error(`Error: ${e}`) } return Promise.resolve(true)

}

Esto se imprimirá

 "isSuccess for stateName false" "isSuccess for stateName true" "isSuccess for stateName true"

Entonces, después de que el indicador cambie a verdadero, continuará durante más bucles. A veces lo hace más de una vez.

¿Estoy haciendo algo mal?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

No puede mezclar un bucle síncrono ( while (!isSuccess) { ... } ) con funciones asíncronas ( redis.watch(stateName, function (err) { ... }) ).

Tampoco puede await funciones asincrónicas basadas en devolución de llamada. Una función debe devolver una promesa para estar disponible. Dado que node-redis le promete cuando no pasa devoluciones de llamada a sus métodos, la clave es no hacer eso ( redis.watch(stateName, function (err) { ... }) → redis.watch(stateName) ) .

Su enfoque necesita ser rehecho.

Hagamos una función que encapsule una transacción redis con bloqueo optimista . Toma un objeto de conexión, una clave y una función de transformación de valores, y devuelve el resultado de la operación .set() :

 const redisTransaction = async (client, key, transformer) => { // https://github.com/redis/node-redis/blob/master/docs/isolated-execution.md return client.executeIsolated(async isolatedClient => { await isolatedClient.watch(key); const val = await isolatedClient.get(key); return isolatedClient.multi() .set(key, await transformer.call(isolatedClient, val)) .exec(); }); };

Ahora puede await esta función, porque devuelve una promesa. Eso significa que podemos hacer un ciclo infinito simple que sale inmediatamente en caso de éxito (a través de return ), o reintenta indefinidamente.

 export async function updateRedis(key, transformer) { while (true) { try { return await redisTransaction(redis, key, transformer); } catch (err) { logger.error(`Error for state ${key}: ${err}`); } } }

Una función de transformador toma un valor y devuelve un nuevo valor. En su interior, la palabra clave this se refiere al cliente isolatedClient de la transacción, lo que podría ser útil si su transformación depende de otros valores de ese cliente.

 const result = await updateRedis('stateName', async function (val) { const state = JSON.parse(val); const newState = await modifyStateSomehow(state); return JSON.stringify(newState); });

El modifyStateSomehow() puede ser en sí mismo una función asíncrona (es decir, "devolución de promesa"). Si no es así, puede hacer que el transformador de estado sea una función normal eliminando async y await .

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!