Рефакторинг кода обратного вызова в async / await - PullRequest
0 голосов
/ 01 марта 2019

У меня есть приложение 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);
}

И вот пример того, как я использую сервис из кода.

модели / инвентарь.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);
  }

next (функция обратного вызова) будет undefined , это нормально, но как мне изменить службу PDF, чтобы она работала с обоими асинхронными вызовами?и со старым способом обратного вызова.(У меня есть много старых шаблонных функций в коде).Любые предложения приветствуются.

1 Ответ

0 голосов
/ 03 марта 2019

async / await будет работать только с обещаниями.Таким образом, ваша функция инвентаризации должна стать обещанием.Я пытался раскрутить ваши функции в надежде облегчить чтение.У меня нет полной базы кода, но, надеюсь, общая идея встречается.В результате могут отсутствовать некоторые переменные и т. Д.

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