我正在了解Javascript Promise
和async
/ await
。下面的示例代码异步读取并解析node.js中的JSON文件(我的node.js版本是v10.0.0 )。
在示例代码中,ChainReadJson函数和AwaitReadJson函数正在做同样的事情,读取和解析JSON文件。区别在于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);
}
使用promise chain编写ChainReadJson函数的代码时,我很难控制执行结果和错误 但是,当使用async / await编写AwaitReadJson函数的代码时,这些困难大多都消失了。
我是否正确理解async / await的好处?与promise链相比,async / await有哪些缺点?
(示例代码是the code in this answer的修改版本。原始代码仅使用promise链,并且编写以确切地知道错误发生在链中的哪个位置以及错误是什么)
答案 0 :(得分:9)
实际上,与回调,承诺和生成器函数相比,.cent {
align: center;
position: absolute;
top: 40%;
left: 45%;
}
是designed来减少样板并使异步程序更容易编写。
答案 1 :(得分:3)
尽管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)
});
}
这里唯一的功能区别是所有错误记录都发生在链的末尾的一个地方。
可以保留readFile和JSON.parse的拆分日志记录,但这无疑是有点棘手的。您通常希望在处理错误后重新抛出错误,以便跳过下游.then
处理程序:但如果再次抛出错误,下游.catch
处理程序将再次捕获该错误。如果您没有找到过滤它的方法,将导致重复记录。
这是可行的,但这有点痛苦,所以我把它从上面的代码中删除了。