调整base64图像大小并从nodejs中的函数中获取return值

Resize base64 image and get the return value out of the function in nodejs

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)

我明白了,SyntaxError: await 仅在异步函数和模块的顶层主体中有效。 但是如果我删除异步并只打印值而不 returning 它,它工作正常。那么我如何能够从该函数中获取值作为 return 值并将其保存在变量中?

您不能 return 异步回调中的值并期望将它们分配给变量。异步回调在稍后的时间点由 Node.js 执行,此时执行上下文丢失。例如,这将不起作用:

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); // undefined

要完成你想要的,你有两个选择:

  1. 使用 promisified 版本的 Jimp 并继续使用 async/await
  2. 将 imgResize 从 async/await 转换为使用回调

事实证明,如果您不传递回调函数,Jimp return 就是一个承诺,因此采用解决方案 #1 是最直接的。 Refactoring from callbacks to async/await 会给我们以下内容:

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);

注意:为此,您需要使用 ES 模块 (ESM) 启用 top-level 等待。否则,您应该将最后一行包装在 IIFE 中:

(async () => {
  const img = await imgResize(base64data);
)();