为什么这个模块 return 未定义?

Why does this module return undefined?

我正在使用 jimp 和 qrcode-reader 在 NodeJs 中编写代码。这些依赖关系运作良好。问题出在我将代码导出到模块中时。据推测,它应该 return 一个值。这是一个箭头函数,return是二维码的URL。但是,如果我使用“console.log”,我可以看到它有效。但是当我使用该模块时,它 return 未定义。也许我错过了一些非常简单的东西。

模块代码如下:

const Jimp = require('jimp')
const fs = require('fs')
const QrCode = require('qrcode-reader')

const scanQR = (source) => {
const buffer = fs.readFileSync(source)

   Jimp.read(buffer, (err, image) => {
       try {
           const qr = new QrCode()
           qr.callback = (error, value) => {
               try {
                   console.log(value.result)
                   return value.result
               } catch(error) {
                   console.error(error)
               }
           }
           qr.decode(image.bitmap)
       } catch (error) {
           console.error(error)
       }
   })
}

module.exports = scanQR

这里是导入的模块:

const scanQR = require('./utils/scanQR')
const qr_code_screenshot = `${__dirname}/assets/images/qrcode-test.png`
const result = scanQR(qr_code_screenshot)
console.log(result)

这是控制台上的结果:

提前致谢。

您的 scanQR 函数没有 returning 任何东西:因此当您分配它的 return 值时,您会得到 undefined。即预期。问题来自于您试图 return 在仅异步触发的回调中调用某些内容。

要解决此问题,您需要将内部逻辑包装在一个 promise 中(returned)。然后,您可以 resolve/reject 根据代码是否成功执行或抛出错误的承诺:

const scanQR = (source) => {
    // Wrap all logic inside a promise, which you return
    return new Promise((resolve, reject) => {
        const buffer = fs.readFileSync(source);

        Jimp.read(buffer, (err, image) => {
            try {
                const qr = new QrCode();
                qr.callback = (error, value) => {
                    try {
                        // Resolve promise here
                        resolve(value.result);
                    } catch(error) {
                        // Reject promise
                        reject(error);
                    }
                }
                qr.decode(image.bitmap);
            } catch (error) {
                reject(error);
            }
        });
    });
}

消耗模块时,您需要使用.then():

const scanQR = require('./utils/scanQR');
const qr_code_screenshot = `${__dirname}/assets/images/qrcode-test.png`;

// `scanQR` returns a promise and you will need to use `.then()`
scanQR(qr_code_screenshot).then(data => console.log(data));

...或使用 async/await:这是实现此目的的众多方法之一:

const scanQR = require('./utils/scanQR');

async function scan(image) {
    const result = await scanQR(image);
    console.log(result);
}

scan(`${__dirname}/assets/images/qrcode-test.png`);