Z
Z
zeuss562017-05-17 17:46:12
JavaScript
zeuss56, 2017-05-17 17:46:12

How to use async/await in Node.JS and other best practices?

Decided to start learning Node.JS with ES6 and TypeScript.
I wrote a static web server according to one screencast, spice it up with arrow functions and promises, I don't use TypeScript yet. I want to use async/await, but I don’t understand how this construction is related to promises and I assume that Node.JS already has functions for convenient work with async/await, I don’t know where to dig.
Tell me how to implement async/await and other technologies to improve readability and code quality in the current code.
Am I making the application right at all?
For those who do not like to click on links, the code in the spoiler:

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));

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
GiperScriper, 2017-05-17
@zeuss56

Here is my example, https://github.com/GiperScriper/Task-Manager-API/b...
async/await style getProjects function

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question