Как использовать async/await в Node.JS и другие best practices?

287
18 мая 2017, 11:27

Решил начать изучение Node.JS с ES6 и TypeScript. Написал статичный веб-сервер согласно одному скринкасту, приправив его стрелочными функциями и промисами, TypeScript пока не использую. Хочу использовать async/await, но не понимаю как эта конструкция связана с промисами и предполагаю, что в Node.JS уже есть функции для удобной работы с async/await, не знаю куда копать. Подскажите, как внедрить async/await и другие технологии для улучшения читабельности и качества кода в текущий код. Правильно ли я вообще делаю приложение?

Код:

// 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));
READ ALSO
Вызов функции только один раз jquery

Вызов функции только один раз jquery

Есть функция jQuery, при вводе текста цели передаются в метрику и аналитикс:

501
Способ укоротить условие WHERE в sql-запросе

Способ укоротить условие WHERE в sql-запросе

Например, есть запрос, в котором я хочу наложить условие, чтобы он мне выдал только те строки, где value > 500:

209
MySQL запрос состоящий из четырех таблиц

MySQL запрос состоящий из четырех таблиц

1) Напишите запрос, который выводит имена всех учеников, сдавших экзамен по математике у профессора Иванова на оценку 4 или 52) Напишите запрос,...

232
SQL запрос UPDATE с группировкой

SQL запрос UPDATE с группировкой

Есть таблица, в которой дублируются REF_DOC_ID

225