1. 程式人生 > >node 進階 | 通過node中如何捕獲異常闡述express的特點

node 進階 | 通過node中如何捕獲異常闡述express的特點

嵌套回調 執行 nod encode request quest alt mon jade

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

  

node 進階 | 通過node中如何捕獲異常闡述express的特點