2

I am trying to get my hands dirty with some node.js code. I understand the theory of events and callbacks and asynchronous techniques, but this does not mean it is easy to really produce code in "the right manner".

The following is my (reallife) example of a middleware. A simple HTTP server listens for requests and on /get, it queries our backend and presents the data from there to the client.

var http = require('http')
var https = require('https')
var url = require('url')

var backendOptions = {
    port: 1414,
    hostname: 'data.backend.com',
    path: '/bulk',
    auth: 'user:$ecret'
}

var backendGet = function(callback) {
    https.get(backendOptions, function(res) {
        var content = ''
        res.on('data', function(chunk) {
            content += chunk
        })
        res.on('end', function() {
            callback(content)
        })
    })
}

var server = http.createServer(function(req, res) {
    switch(url.parse(req.url).pathname) {
        case '/get':
            backendGet(function(content) {
                res.writeHead(200, {'Content-Type': 'text/plain'})
                res.write(content)
                res.end()
            })
            break
        default:
            res.writeHead(200, {'Content-Type': 'text/html'})
            res.write('<p>It works!</p>')
            res.end()
    }
}).listen(8080, 'localhost')

This code works - but is this how I write code in node.js? The client should be served when the data from backend is available, so I'm calling backendGet() with a function as callback to operate on the res object as soon as there is no more backend data to be read.

General comments and critique are welcome, too!

Alex

4

1 回答 1

2

这看起来很扎实。我会做一些调整,最大的是,回调具有函数签名是常规的function callback(err, result1, result2..)callback(null, content)如果它有效,callback('Problem')或者callback(new Error('Problem'))如果它没有,你打电话。

我使用上述约定添加了错误处理。AFAIK 缺少尾随分号并没有破坏任何东西,但我出于习惯添加了它们。我将处理请求的匿名函数移到了它自己的函数中以使其更清晰。最后我重新缩进了 2 个空格,因为它使回调地狱更易于管理。

var http = require('http');
var https = require('https');
var url = require('url');

var backendOptions = {
  port: 1414,
  hostname: 'data.backend.com',
  path: '/bulk',
  auth: 'user:$ecret'
};

var backendGet = function(callback) {
  https.get(backendOptions, function(res) {
    var content = '';
    res.on('data', function(chunk) {
      content += chunk;
    });
    res.on('end', function() {
      callback(null, content);
    });
    res.on('error', function(err) {  
      // i didn't look up this syntax but I think this is how errors are signified
      console.log('Request error: '+err);
      callback('Request error');
    });
  });
};

function handler(req, res){
  switch(url.parse(req.url).pathname) {
    case '/get':
      backendGet(function(err, content) {
        if(err){
          res.writeHead(500, {'Content-Type': 'text/plain'});
          res.write('Request error');
          return res.end();
        };
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.write(content);
        res.end();
      })
      break;
    default:
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write('<p>It works!</p>');
      res.end();
  }
};

var server = http.createServer(handler).listen(8080, 'localhost');
于 2013-08-09T13:24:09.880 回答