调整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
要完成你想要的,你有两个选择:
- 使用 promisified 版本的 Jimp 并继续使用 async/await
- 将 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);
)();
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
要完成你想要的,你有两个选择:
- 使用 promisified 版本的 Jimp 并继续使用 async/await
- 将 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);
)();