将回调代码重构为async / await

问题描述 投票:0回答:1

我有一个node.js /(基于表达式)的loopback.js应用程序,带有一个使用HtmlToPDF的PDF服务来生成PDF。

一些代码:

服务/ pdf.js

exports.PDF = function(options, cb) {
  // ...
  var htmlToPDF = new HTMLToPDF({
    // ... options
  });

  function sendBackFile(outputPath, cb) {
    fs.readFile(outputPath, function (err, data) {
      if (err) {cb(err)}
      var contentDisposition = 'attachment; filename=' + filename + '.pdf';
      cb(null, data, 'application/pdf', contentDisposition, 'SAMEORIGIN');
    })
  }
  // start / stop Xvfb code ...
  htmlToPDF.build(function (err) {
    if (err) {cb(err)};
    // read the file and send it back
    sendBackFile(outputPath, cb)
  });
}

对于不同类型的PDF,我有不同的模板。 (对于不同的名称,outputPath,模板等每种类型)

exports.invetory = function(html, cb) {
  exports.PDF({
    html: html
  }, cb);
}

这是一个例子,我如何使用代码中的服务。

车型/ inventory.js

  Inventory.pdf = (id, next) => {
    pdf.inventory('yo', next);
  }

分解

  1. 将PDF服务导入代码,并调用库存模板
  2. 清单模板调用PDF服务
  3. PDF服务启动htmlToPDF实例,创建PDF并将其另存为文件。
  4. 从磁盘读取文件,API将其发回。

这个问题

我尝试使我的Inventory.pdf函数异步/等待意识到。但如果我这样做

  Inventory.pdf = async (id, next) => {
    return await pdf.inventory('yo', next);
  }

接下来,(回调函数)将是未定义的,这没关系,但是我应该如何更改PDF服务,使其与异步调用一起使用,以及使用旧的回调方式。 (我在代码中有很多旧模板功能)。任何建议都非常受欢迎。

node.js async-await loopbackjs html-to-pdf
1个回答
1
投票

async / await只适用于promises。所以你的库存功能需要成为一个承诺。我试图解除你的功能,希望能让它更容易阅读。我没有完整的代码库,但希望总体想法能够实现。结果可能会丢失一些变量等。

// Build HTML to PDF
exports.htmlToPDF = function() {
  return new Promise(async (resolve, reject) => {
    let htmlToPDFData;

    try {
      htmlToPDFData = await htmlToPDF.build();
    } catch (err) {
      reject(err);
      return;
    }

    resolve(htmlToPDFData);
  });
};

// Read data from a file
exports.sendBackFile = function(outputPath) {
  return new Promise(async (resolve, reject) => {
    let fileData;

    try {
      fileData = await fsReadFile(outputPath, "utf8");
    } catch (err) {
      reject(err);
      return;
    }

    resolve(fileData);
  });
};

exports.PDF = function(options) {
  return new Promise(async (resolve, reject) => {
    // ...
    const htmlToPDF = new HTMLToPDF({
      // ... options
    });

    let backFileData;
    let htmlToPDFData;

    try {
      backFileData = await exports.sendBackFile(outputPath);
    } catch (err) {
      reject(err);
    }

    const contentDisposition = `attachment; filename=${filename}.pdf`;

    // Assuming this function is not a promise we just call it. Originally this was one of the callback functions.
    callWhateverFunctionWeNeedTo(
      null,
      backFileData,
      "application/pdf",
      contentDisposition,
      "SAMEORIGIN"
    );

    // start / stop Xvfb code ...
    try {
      htmlToPDFData = await exports.htmlToPDF();
    } catch (err) {
      reject(err);
    }

    // Read the file and send it back
    try {
      await exports.sendBackFile(htmlToPDFData);
    } catch (err) {
      reject(err);
    }
  });
};

// Call inventory
exports.invetory = function(html) {
  return new Promise(async (resolve, reject) => {
    try {
      await exports.PDF({ html });
    } catch (err) {
      reject(err);
    }

    resolve();
  });
};

Inventory.pdf = async (id, next) => {
  try {
    await pdf.inventory("yo");
  } catch (err) {
    console.log(err);
    return;
  }

  next();
};
© www.soinside.com 2019 - 2024. All rights reserved.