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,晚安
node 進階 | 通過node中如何捕獲異常闡述express的特點