将回调代码重构为异步/等待状态

时间:2019-03-01 13:07:36

标签: node.js async-await loopbackjs html-to-pdf

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

某些代码:

services / 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);
}

这是一个示例,说明如何使用代码中的服务。

models / 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);
  }

接下来,(回调函数)将为 undefined ,没关系,但是我应该如何更改PDF服务,以使其既可用于异步调用,又可用于旧的回调方法。 (我在代码中有许多旧的模板函数)。任何建议都值得欢迎。

1 个答案:

答案 0 :(得分:1)

async / await仅在promise中起作用。因此,您的库存功能将需要兑现。我试图取消嵌套您的功能,希望使其更易于阅读。我没有完整的代码库,但希望能遇到一般的想法。结果可能会缺少一些var等。

// 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();
};