node.js - 将回调代码重构为 async / await
问题描述
我有一个 node.js /(基于 express)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,我有不同的模板。(对于每种类型的不同名称、输出路径、模板等)
exports.invetory = function(html, cb) {
exports.PDF({
html: html
}, cb);
}
这是一个示例,我如何使用代码中的服务。
模型/inventory.js
Inventory.pdf = (id, next) => {
pdf.inventory('yo', next);
}
分解
- PDF服务导入代码,调用库存模板
- 库存模板调用 PDF 服务
- PDF 服务启动一个 htmlToPDF 实例,创建一个 PDF 并保存为文件。
- 从磁盘读取文件,然后 API 将其发回。
问题
我尝试使我的Inventory.pdf
函数具有异步/等待意识。但如果我这样做
Inventory.pdf = async (id, next) => {
return await pdf.inventory('yo', next);
}
接下来,(回调函数)将是undefined,没关系,但是我应该如何更改 PDF 服务,以使其与异步调用和旧回调方式一起工作。(我在代码中有很多旧模板函数)。任何建议都非常受欢迎。
解决方案
async/await 仅适用于 Promise。所以你的库存功能需要成为一个承诺。我试图取消嵌套您的函数,希望使其更易于阅读。我没有完整的代码库,但希望能得到大致的想法。结果可能会丢失一些变量等。
// 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();
};
推荐阅读
- java - 使用谷歌云 Mysql 部署到 Heroku 的 Spring Boot 应用程序
- django - 服务“web”中“环境”选项的插值格式无效:“SECRET_KEY=
- python - 如何在 Python 数据集中传递 postgre sql 模式
- python - y_pred = regressor.predict(sc_X.transform(6.5)) 不工作
- c# - Powershell cmdlet 中的 C# 代码不输出值
- google-apps-script - 匹配时比较列 A、B 和 C 并返回 col D 的值
- java - 我可以在另一台计算机的 chorme 浏览器中运行我的 selenium WebDriver 代码吗?
- python - 安装scrapy时如何解决“退出状态2失败”?
- sql - 如何组合结果表中的 2 列?
- sql - 当互联网应用程序的输入是 SQL 语句的一部分时,会有哪些安全问题?