Odjakživa co píšu v NodeJS se držím callbackového zápisu asynchronních funkcí. Callback-hellu se snažím vyhnout rozumnou dekompozicí řešené úlohy a Promises zápis mě nikdy nedostal… Nicméně s jazykovou konstrukcí async/await, která se do JavaScriptu dostala ve verzi ES2017, se dá leckdy kód napsat čitelněji, pochopitelněji a tím pádem snad i bezpečněji.
Takhle by tedy mohl vypadat kód pro čtení dat z MongoDB:
Původní callback implementace
// nejake Expressjs obsluha routy, ktera cte z databaze uzivatele
const MongoClient = require('mongodb').MongoClient;
function getUsers(req, res) {
MongoClient.connect(process.env.MONGOURL, { useNewUrlParser: true }, (err, client) => {
if (err) {
res.status(501).json({
msg: 'mongodb connect error',
detail: err.message
});
} else {
let mongoAccontCollection = client.db(process.env.MONGODB).collection(process.env.MONGOCOL);
mongoAccontCollection.findOne({ email: req.body.email }, (err, account) => {
client.close();
if (err) {
res.status(501).json({
msg: 'mongodb find error',
detail: err.message
});
} else {
if (account) {
res.status(200).json(account});
else
res.status(400).json({
msg: 'account not found'
});
}
});
}
});
}
Nová async/await implementace
// opet Expressjs funkce s obsluhou routy pro vycitani dat z databaze
const MongoClient = require('mongodb').MongoClient;
async function getUser(req, res) {
try {
let client = await MongoClient.connect(process.env.MONGOURL, { useNewUrlParser: true });
let user = await client
.db(process.env.MONGODB)
.collection(process.env.MONGOCOL)
.findOne();
client.close();
if (user) res.status(200).json(user);
else res.status(400).json({msg: 'account not found'});
} catch (err) {
res.status(500).json({
msg: err.message
});
}
}
Resumé
Na první pohled jde vidět několik věcí: ošetření všech chyb se přesouvá jen do jednoho místa a tím odpadá mnoho opakujícího se kódu, výsledek, načtená data nejsou nikde hluboce zanořená a nemusíte řešit problém s kaskádou otevřených závorek if-else větví.
Nutno podotknout, že výhoda nového zápisu ještě více vzroste v momentě, kdy máte sérii callback dotazů a obslužný kód vám začne ještě více narůstat.
Vedle toho si samozřejmě dokáži představit kód, kde bych se dál držel callback zápisu, ale to je věc konkrétního použití.