这是在node.js中编写异步代码的正确方法吗?

时间:2013-08-09 13:13:11

标签: javascript node.js asynchronous

我试图用一些node.js代码弄脏手。我理解事件和回调以及异步技术的理论,但这并不意味着以“正确的方式”真正地生成代码很容易。

以下是我的(reallife)中间件示例。一个简单的HTTP服务器侦听请求,在/get上,它查询我们的后端并将数据从那里呈现给客户端。

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

此代码有效 - 但这是我在node.js中编写代码的方法吗?当来自后端的数据可用时,应该提供客户端,所以我正在调用backendGet()一旦没有更多的后端数据被读取,就可以作为回调来对res对象进行操作。

也欢迎一般评论和批评!

亚历

1 个答案:

答案 0 :(得分: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');