国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

nodejs對(duì)express中next函數(shù)的一些理解

2024-05-06 15:27:01
字體:
供稿:網(wǎng)友

最近公司在使用node做前后端分離,采用的web框架是express,所以對(duì)express框架進(jìn)行了深入的了解,前段時(shí)間寫了篇關(guān)于express路由的文章,但是在那篇文章中貌似少了一個(gè)很重要的內(nèi)容,就是express的next,所以今天單獨(dú)來說說express的next。

關(guān)于next主要從三點(diǎn)來進(jìn)行說明:

next的作用是什么? 我們應(yīng)該在何時(shí)使用next? next的內(nèi)部實(shí)現(xiàn)機(jī)制是什么?

Next的作用

我們?cè)诙xexpress中間件函數(shù)的時(shí)候都會(huì)將第三個(gè)參數(shù)定義為next,這個(gè)next就是我們今天的主角,next函數(shù)主要負(fù)責(zé)將控制權(quán)交給下一個(gè)中間件,如果當(dāng)前中間件沒有終結(jié)請(qǐng)求,并且next沒有被調(diào)用,那么請(qǐng)求將被掛起,后邊定義的中間件將得不到被執(zhí)行的機(jī)會(huì)。

何時(shí)使用Next

從上邊的描述我們已經(jīng)知道,next函數(shù)主要是用來確保所有注冊(cè)的中間件被一個(gè)接一個(gè)的執(zhí)行,那么我們就應(yīng)該在所有的中間件中調(diào)用next函數(shù),但有一個(gè)特例,如果我們定義的中間件終結(jié)了本次請(qǐng)求,那就不應(yīng)該再調(diào)用next函數(shù),否則就可能會(huì)出問題,我們來看段代碼

app.get('/a', function(req, res, next) {  res.send('sucess');  next();});// catch 404 and forward to error handlerapp.use(function(req, res, next) { console.log(404); var err = new Error('Not Found'); err.status = 404; next(err);});app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', {  message: err.message,  error: {} });});

發(fā)送請(qǐng)求"/a",控制臺(tái)打印日志如下:

404GET /a 500 6.837 ms - -Error: Can't set headers after they are sent.  at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:345:11)

為什么代碼會(huì)拋異常呢,就是因?yàn)槲覀冊(cè)趓es.send之后調(diào)用了next函數(shù),雖然我們本次的請(qǐng)求已經(jīng)被終止,但后邊的404中間件依舊會(huì)被執(zhí)行,而后邊的中間件試圖去向res的headers中添加屬性值,所以就會(huì)拋出上邊的異常。

讀到這你可能會(huì)有個(gè)疑問,如果我不在res.send后邊調(diào)用next函數(shù),那后邊定義的404中間件是不是永遠(yuǎn)都不會(huì)被執(zhí)行到。現(xiàn)在我們刪除res.send后邊next函數(shù)調(diào)用,發(fā)送請(qǐng)求"/xxx",我們就會(huì)發(fā)現(xiàn)404中間件被執(zhí)行了,(ㄒoㄒ),這不是和我們之前說的矛盾了嗎,我們的自定義中間件沒有調(diào)用next,但后邊定義的中間件仍舊被執(zhí)行了,這究竟是為什么呢。看來只能求助源碼了~~~

Next的內(nèi)部機(jī)制

function next(err) {  ... //此處源碼省略  // find next matching layer  var layer;  var match;  var route;  while (match !== true && idx < stack.length) {   layer = stack[idx++];   match = matchLayer(layer, path);   route = layer.route;   if (typeof match !== 'boolean') {    // hold on to layerError    layerError = layerError || match;   }   if (match !== true) {    continue;   }   ... //此處源碼省略  } ... //此處源碼省略  // this should be done for the layer  if (err) {    layer.handle_error(err, req, res, next);  } else {   layer.handle_request(req, res, next);  } }            
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 文昌市| 新郑市| 山阴县| 修武县| 闵行区| 贵德县| 涿州市| 山东省| 天气| 明溪县| 封丘县| 嘉黎县| 白朗县| 垣曲县| 宜川县| 合肥市| 永济市| 永德县| 卓尼县| 鄯善县| 靖州| 来安县| 益阳市| 浑源县| 江津市| 普洱| 台东县| 武平县| 襄垣县| 铁力市| 江山市| 舒兰市| 图们市| 绥滨县| 加查县| 辉南县| 铁岭市| 太康县| 海南省| 阿克苏市| 苗栗县|