Tengo una aplicación CRUD básica que usa formularios html, nodejs/express y mongodb. He estado aprendiendo sobre el código síncrono frente al código asíncrono a través de devoluciones de llamada, promesas y asíncrono/espera y, según tengo entendido, para una aplicación cruda, le gustaría que las operaciones fueran asíncronas para que varios usuarios puedan realizar las operaciones al mismo tiempo. Estoy tratando de implementar aync/await con mis operaciones Express Crud y no estoy seguro de si se ejecutan de forma síncrona o asíncrona.
Aquí está mi función de actualización, que permite a un usuario escribir el _id del blog que desea cambiar, luego escribir un nuevo título y un nuevo cuerpo para el blog y enviarlo. En su estado actual, que yo sepa, se está ejecutando sincrónicamente:
app.post('/update', (req, res) => { const oldValue = { _id: new mongodb.ObjectId(String(req.body.previousValue)) } const newValues = { $set: { blogTitle: req.body.newValue, blogBody: req.body.newValue2 } } db.collection("miscData").updateOne(oldValue, newValues, function (err, result) { if (err) throw err; console.log("1 document updated"); res.redirect('/') }); })La forma en que iba a cambiar esto a asíncrono era así:
app.post('/update', async (req, res) => { const oldValue = { _id: new mongodb.ObjectId(String(req.body.previousValue)) } const newValues = { $set: { blogTitle: req.body.newValue, blogBody: req.body.newValue2 } } await db.collection("miscData").updateOne(oldValue, newValues, function (err, result) { if (err) throw err; console.log("1 document updated"); res.redirect('/') }); })Ambos bloques de código funcionan, sin embargo, no estoy seguro de si el segundo bloque de código está haciendo lo que pretendo que haga, que es permitir que un usuario actualice un blog sin bloquear la pila de llamadas, o si el segundo bloque de código haría solo tiene sentido si estuviera ejecutando más funciones después de la espera. ¿Esto logra el propósito previsto, si no, cómo podría/debería hacerlo?
db.collection(...).updateOne siempre es asíncrono, por lo que no debe preocuparse de que una operación de base de datos de ejecución prolongada pueda bloquear su aplicación. Hay dos formas de obtener el resultado asíncrono:
db.collection(...).updateOne(oldValues, newValues, function(err, result) {...}); console.log("This happens synchronously"); La función de devolución de llamada con los dos parámetros (err, result) se llamará de forma asíncrona, después de que se haya completado la operación de la base de datos (y después de console.log ). err contiene un mensaje de error de la base de datos o result contiene el resultado de la base de datos.
try { var result = await db.collection(...).updateOne(oldValues, newValues); // Do something with result } catch(err) { // Do something with err } console.log("This happens asynchronously"); La función updateOne sin una función de devolución de llamada como tercer parámetro devuelve una promesa que debe await . Las declaraciones que hacen algo con el result se ejecutarán de forma asíncrona, después de que la operación de la base de datos se haya completado con éxito. Si se produce un error en la base de datos, en su lugar se ejecutan las sentencias del bloque catch . En cualquier caso (éxito o error), el console.log solo se ejecuta después.
(Si updateOne no tiene una versión de dos parámetros, puede escribir
var result = await util.promisify(db.collection(...).updateOne)(oldValues, newValues); usando util.promisify .)
Su segundo fragmento de código contiene una combinación de ambas formas (tercer parámetro más await ), lo que no tiene sentido.