Решил начать изучение Node.JS с ES6 и TypeScript.
Написал
статичный веб-сервер согласно одному скринкасту, приправив его стрелочными функциями и промисами, TypeScript пока не использую. Хочу использовать async/await, но не понимаю как эта конструкция связана с промисами и предполагаю, что в Node.JS уже есть функции для удобной работы с async/await, не знаю куда копать.
Подскажите, как внедрить async/await и другие технологии для улучшения читабельности и качества кода в текущий код.
Правильно ли я вообще делаю приложение?
Для тех, кто не любит нажимать на ссылки, код в спойлере:
spoiler// Require libs
const http = require('http');
const fs = require('fs');
const url = require('url');
const path = require('path');
const domain = require('domain');
// Prepare arguments
let args = [];
process.argv.forEach(val => {
let arg = val.split('=', 2);
if (arg[1]) args[arg[0]] = arg[1].replace(/^"(.*)"$/, '$1');
});
// Check required args
if (!args.port || !args.path) {
console.error('Bad start. Use "port" and "path" arguments to configure server.');
process.exit(0);
}
// Server wrapper
let serverDomain = domain.create();
// Run server in wrapper
serverDomain.run(() => {
// Server
let server = http.createServer((req, res) => {
// Run request in wrapper
let reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
// Processing request
reqDomain.run(() => {
let filePath;
try {
// Prepare file path
filePath = decodeURIComponent(url.parse(req.url).pathname);
if (~filePath.indexOf('\0') || ~filePath.indexOf('..')) throw new Error();
filePath = path.normalize(path.join(args.path, filePath));
} catch (e) {
// 400 Bad Request
res.statusCode = 400;
res.end('Bad Request');
return;
}
new Promise((resolve, reject) => {
fs.stat(filePath, (err, stats) => {
if (err || !stats.isFile())
reject(stats);
else
resolve(stats);
});
})
// On error
.catch(stats => {
// 404 Not Found
res.statusCode = 404;
res.end('Not Found');
})
// On success
.then(stats => {
// Compute MIME-type
let ext = path.extname(filePath);
let mimetype = require('./mime')[ext];
res.setHeader('Content-Type', mimetype);
// Output
let fstream = fs.ReadStream(filePath);
fstream.pipe(res);
fstream.on('error', err => reqDomain.emit('error', err));
res.on('close', () => fstream.destroy());
});
});
// On request error
reqDomain.on('error', err => {
// 500 Server Error
res.statusCode = 500;
res.end('Server Error');
console.error(err);
});
});
// Run server
server.listen(args.port, () => console.log(`Server running at ${args.port} port in ${args.path}`));
});
// On server error
serverDomain.on('error', err => console.error(err));