node 进阶 | 通过node中如何捕获异常阐述express的特点

冷暖自知 提交于 2020-04-01 09:01:13

node如何捕获异常

    node基于js的单线程,有了非阻塞异步回调的概念,但是在处理多个并发连接时,并发环境要求高,最重要的是单线程,单核CPU,一个进程crash则web服务都crash,但是为什么node还这么火?甚至有了Node工程师这个岗,肯定就是node有自己crash之前与之后的解决方法,比如捕获异常

   问:nodejs如何捕获异常?答:回调函数中有err形参,console.log出来,这是我之前回答别人问题的答案,但是自从我这几天看了如何捕获异常,才知道捕获异常的精髓就是不要让服务crash掉,抛出500状态码。而我回答的是风马牛不相及。

    一般如何捕获异常

   1、使用uncaughtExprection去捕获异常

process.on("uncaughtExpection",function(err){
      console.log(err)         
})

   2、用try-catch在回调函数前捕获异常    

var http = require('http');

http.createServer(function(req, res) {
  try {
    fn(req, res);
  } catch(e) {
    console.log(e.stack);
    res.end("Error")
  }
}).listen(3000);

function fn (req, res) {
  var name = req.body.name;
  res.end("回调函数");
};

   3、用框架去包住,捕获异常,express做的好

app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handler
app.use(function(err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});
  特殊情况如何捕获异常

  如果在回调函数中如何捕获异常呢?

  如果是回调函数中捕获异常怎么做?用domain去捕获,domian捕获会抛出500错误,但是domain捕获有一个问题,会丢失栈信息,无法保证程序健康进行,所以要结束进程,在回调函数中process.exit(1),然后用node的server.close方法再去释放,server.close连接释放后自动结束进程,所以不用在server.close中去结束进程process.exit(1)
  uncaughtExpection捕获异常的的原理就是:uncaughtExpection事件存在回调函数process.on("uncaughtExpection",callback)时node不会强制结束进程,这样可弥补domain丢失stack的问题
  所以domian去捕获绝大部分回调函数中的异常,uncaughtExpection去捕获丢失stack异常,这样就完整了

  uncaughtExprection+domain去捕获回调函数中的异常就ok

  app.use(function(req,res,next){
      var reqDomain = domain.create();
      reqDomain.on("err",function(){
        try {
          var killTimer = setTimeout(function(){
            process.exit(1);
          },1000)
          killTimer.unref();
          server.close();
          res.send(500);
        } catch(e) {
          // statements
          console.log(e.stack);
        }
      })
      reqDomain.run(next);
  });
process.on("uncaughtException",function(err){
  console.log(err);
  try{
    var killTimer = setTimeout(function(){
      process.exit(1)
    },1000)
    killTimer.unref();
    server.close();
  }catch(e){
    console.log(e.stack);
  }
});

express特点

  express的优点

  1、对node的HTTP封装好了,直接去app.listen

  2、中间件完成了post/get请求,回调函数中有req,res,next,其中next的作用就是把请求传递给下一个中间件,比如两次使用use中间件去处理同一请求,用next传递可以同时处理

  3、对post封装的很好,post中node中是这样写的

      function onRequest(req,res){
        req.addListener("data",function(postdata){
            //data
        })
        req.addListener("end",function(){
            //router
        })
      }

 实现post请求需要监听两次事件:"data"、"end"。先执行data事件,data事件接收数据块,接收完毕且成功,再触发一次end事件,将post的数据返还给路由

  而app.post就完成了,最多需要设定

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));

  用于接收post请求的参数

  4、内置路由,提高了代码复用率

    

app.use('/', index);

  5、node没有web容器的概念,express有设置了静态文件夹

app.use(express.static(path.join(__dirname, 'public')));

  6、设置了ejs/jade模版引擎

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

  7、对cookie、mongoDB等操作良好

  8、npm、require包或文件非常方便

  etc...

  express缺点

  与express框架同一个类型的有koa hapi 等,没用过后两个,不好评价

  据说一个尴尬的缺点,一个问题express有多个操纵方法

  还有一个,回调函数中嵌套回调函数,容易引用错误的变量,或者无意中改了外部变量

  了解更多点这里

  其实node如何捕获异常和express的特点,这两个问题是电面蚂蚁金服问的问题,我回答的不好,所以连夜回顾,整体,分析,总结

  好了,今天的进阶完毕,下次更新就是分析js所有的异步操作,包括ES6的Promise和ES7的async/await,晚安

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!