[英]Javascript : promise chain vs. async/await?
I am learning about Javascript Promise
and async
/ await
.我正在学习 Javascript Promise
和async
/ await
。 The sample code below asynchronously reads and parses a JSON file in node.js ( my node.js version is v10.0.0 ).下面的示例代码异步读取并解析 node.js 中的 JSON 文件(我的 node.js 版本是 v10.0.0 )。
In the sample code, ChainReadJson function and AwaitReadJson function are doing the same thing, reading and parsing a JSON file.在示例代码中,ChainReadJson 函数和 AwaitReadJson 函数在做同样的事情,读取和解析 JSON 文件。 The difference is that ChainReadJson function uses a promise chain, while AwaitReadJson function uses async/await.不同之处在于 ChainReadJson 函数使用了一个 promise 链,而 AwaitReadJson 函数使用了 async/await。
const FS = require("fs");
function ReadFile(fileName) {
return new Promise((Resolve, Reject) => {
FS.readFile(fileName, 'utf8', (error, result) => {
if (error)
Reject(error);
else
Resolve(result);
});
});
}
// function using promise chain
function ChainReadJson(fileName, CallBack) {
ReadFile(fileName)
.then(
res => JSON.parse(res),
err => {
Message(-1, err.message);
}
)
.then(
res => {
if (res !== undefined)
CallBack(fileName, res);
},
err => {
Message(-2, err.message);
}
);
}
// function using async/await
async function AwaitReadJson(fileName, CallBack) {
let res, json;
try {
res = await ReadFile(fileName);
}
catch (err) {
Message(-1, err.message);
return;
}
try {
json = JSON.parse(res);
}
catch (err) {
Message(-2, err.message);
return;
}
CallBack(fileName, json);
}
ChainReadJson('test.json', PrintJSON);
AwaitReadJson('test.json', PrintJSON);
// common functions
function PrintJSON(fileName, json) {
console.log(`JSON[${fileName}]:`, json);
}
function Message(n, str) {
console.log(`[${n}]`, str);
}
When writing the code for ChainReadJson function using promise chain, I had difficulties controlling execution results and errors.在使用承诺链为 ChainReadJson 函数编写代码时,我很难控制执行结果和错误。 However, when writing the code for AwaitReadJson function using async/await, those difficulties are mostly disappeared.但是,当使用 async/await 编写 AwaitReadJson 函数的代码时,这些困难大多消失了。
Do I correctly understand the benefits of async/await?我是否正确理解 async/await 的好处? What are the disadvantages of async/await compared to promise chain?与承诺链相比,async/await 的缺点是什么?
(The sample code is a modified version of the code in this answer . The original code uses promise chain only, and is written to know exactly where in the chain the error occurred and what is the error) (示例代码是此答案中代码的修改版本。原始代码仅使用承诺链,并编写以确切了解错误发生在链中的哪个位置以及错误是什么)
Indeed, async/await
were designed to reduce boilerplate and make asynchronous programs easier to write, compared to callbacks, promises, and generator functions.实际上,与回调、promise 和生成器函数相比, async/await
旨在减少样板代码并使异步程序更易于编写。
While async/await
can be a nice way to cleanup asynchronous logic, it's worth pointing out that the promise logic can be cleaned up significantly, to the point of being very similar to the async/await alternative:虽然async/await
是清理异步逻辑的好方法,但值得指出的是,promise 逻辑可以被显着清理,与 async/await 替代方案非常相似:
const fs = require("fs");
const util = require("util")
//Could also use the experimental "fs/promise" api from node v10
const promisifiedReadFile = util.promisify(fs.readFile);
const readFile = (fileName) => promisifiedReadFile(fileName, 'utf8');
function chainReadJson(fileName, callback) {
return readFile(fileName)
.then(json => JSON.parse(json))
.then(result => callback(null, result))
.catch(e => {
console.log("Error reading or parsing file", e.message);
callback(e)
});
}
The only functional difference here is that all the error logging occurs at one place, at the end of the chain.这里唯一的功能区别是所有的错误日志都发生在一个地方,在链的末端。
It's possible to preserve the split logging for the readFile and the JSON.parse, but that is admittedly a bit trickier.可以保留 readFile 和 JSON.parse 的拆分日志记录,但这无疑有点棘手。 You generally want to re-throw errors after handling them, so that the downstream .then
handlers are skipped: but if you throw the error again, it'll be caught again by the downstream .catch
handlers, which will cause duplicate logging, if you don't find a way to filter it out.通常你想重新抛出错误处理它们后,使下游.then
处理程序跳过:但如果你再扔的错误,它会再次被抓住下游.catch
处理程序,这将导致重复记录,如果你找不到过滤掉它的方法。
It's doable, but it's a bit of a pain, so I left it out of the above code.这是可行的,但有点痛苦,所以我把它从上面的代码中去掉了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.