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


    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,晚安

      

  • 相关阅读:
    代表行为已成为习惯的信号有哪些?
    Java使用JDBC连接Oracle数据库
    JS正则表达式
    java实现内网通信
    纯前端代码实现美团外卖页面
    HTML绘制表格
    教你如何使用谷歌浏览器,亲测可用!
    Java 多线程实现多窗口同时售票简单功能
    实现获取命令行的返回结果
    HTML模仿实现京东登录页面
  • 原文地址:https://www.cnblogs.com/dirkhe/p/7368357.html
Copyright © 2020-2023  润新知