async function imgResize(data){ // Convert base64 to buffer => <Buffer ff d8 ff db 00 43 00 ... const buffer = Buffer.from(data, "base64"); Jimp.read(buffer, (err, res) => { if (err) throw new Error(err); console.log("Original image size: "+res.getWidth()+"x"+res.getHeight()) if (res.getWidth() > 1025){ res.resize(1025, Jimp.AUTO) console.log("resized image size: "+res.getWidth()+"x"+res.getHeight()) } res.getBase64(Jimp.AUTO, (err, value)=>{ if(err){return err)} return value; }) } const img = await imgResize(base64data)Obtengo, SyntaxError: await solo es válido en funciones asíncronas y los cuerpos de módulos de nivel superior. Pero si elimino el asíncrono y solo imprimo el valor sin devolverlo, funciona bien. Entonces, ¿cómo podré obtener el valor de esa función como valor de retorno y mantenerlo en una variable?
No puede devolver valores dentro de una devolución de llamada asincrónica y esperar que se asignen a una variable. Node.js ejecuta las devoluciones de llamada asincrónicas en un momento posterior, momento en el que se pierde el contexto de ejecución. Por ejemplo, esto no funcionará:
function getImageWidth(buffer) { Jimp.read(buffer, (err, res) => { // Outside context is lost and returning here doesn't // affect the return value of `getImageWidth` parent function return res.getWidth(); // won't work 🚫 } } const width = getImageWidth(buffer); console.log(width); // undefinedPara lograr lo que quieres, tienes dos opciones:
Resulta que Jimp devuelve una promesa si no pasa una función de devolución de llamada, por lo que optar por la solución n. ° 1 es más sencillo. La refactorización de devoluciones de llamada a async/await nos daría lo siguiente:
async function imgResize(data) { const buffer = Buffer.from(data, "base64"); const res = await Jimp.read(buffer); console.log(`Original image size: ${res.getWidth()} x ${res.getHeight()}`); if (res.getWidth() > 1025){ res.resize(1025, Jimp.AUTO); console.log(`Resized image size: ${res.getWidth()} x ${res.getHeight()}`); } return res.getBase64Async(Jimp.AUTO); } const img = await imgResize(base64data);Nota: Para que esto funcione, debe tener habilitada la espera de nivel superior mediante el uso de Módulos ES (ESM). De lo contrario, debe envolver la última línea en un IIFE:
(async () => { const img = await imgResize(base64data); )();