다음 기능을 표현합니다. 실제로 무엇을위한 것입니까?


124

next()방법이 무엇을하는지에 대한 좋은 설명을 찾으려고 노력해 왔습니다 . Express 문서에서는 next('route')해당 경로로 이동하고 그 사이의 모든 경로를 건너 뛰는 데 사용할 수 있다고 말하지만 때로는 next인수없이 호출됩니다. 누구나 next기능 을 설명하는 좋은 튜토리얼 등을 알고 있습니까?

답변:


161

next()아무 주장없이 "농담이야, 나는 이것을 실제로 처리하고 싶지 않다"라고 말한다. 다시 들어가서 일치하는 다음 경로를 찾으려고합니다.

예를 들어 URL 슬러그가있는 일종의 페이지 관리자와 기타 많은 기능을 원할 경우 유용하지만 여기에 예가 있습니다.

app.get('/:pageslug', function(req, res, next){
  var page = db.findPage(req.params.pageslug);
  if (page) {
    res.send(page.body);
  } else {
    next();
  }
});

app.get('/other_routes', function() {
  //...
});

구성한 코드는 데이터베이스에서 특정 ID 슬러그가있는 페이지를 확인해야합니다. 하나를 찾으면 렌더링하십시오! 하나를 찾지 못하면이 경로 처리기를 무시하고 다른 처리기를 확인하십시오.

따라서 next()인수가 없으면 경로를 처리하지 않은 척할 수 있으므로 다른 사람이 대신 선택할 수 있습니다.


또는 app.all('*'). 이를 통해 공유 설정 코드를 실행 한 다음 다른 경로로 이동하여보다 구체적인 작업을 수행 할 수 있습니다.

app.all('*', function(req, res, next){
  myHitCounter.count += 1;
  next();
});

app.get('/other_routes', function() {
  //...
});

좋은 대답입니다! next (err) 및 next ( 'route')와 같이 next의 다른 사용법도 보았습니다. 이제 이러한 목적이 있습니까? 언제 오류를 전파하고 언제 특정 경로로 건너 뛰고 싶습니까?
Andreas Selenwall 2010 년

8
@AndreasSelenwall next('route')은 특정 app.VERB()경로에 " 나머지 경로 콜백을 우회하기위한 여러 콜백이있을 때 사용됩니다 . " next(err)는 게시물의 " 오류 미들웨어 " 로 이동하는 데 사용됩니다 E.
Jonathan Lonowski

5
찬성. "농담입니다. 실제로 처리하고 싶지 않습니다."라는 문구 만 있으면 내가 뭘 찾고 있는지 이해하게되었습니다. 비슷한 질문을 많이 보았고 한 구절에서 해결책을 찾았습니다.
Pedro Barros 2016 년

8
next()인수없이 호출 한다고해서 시스템에 "나는 이것을 처리하고 싶지 않다"고 말하는 것이 아니라,이 작업이 완료된 후에도 나머지 미들웨어를 계속 처리하도록 시스템에 지시 할뿐입니다. 를 호출하는 것은 오류 조건 next()이 아니라 정상적인 흐름의 일부입니다. 전화 next()하지 않으면 다른 경로는 전혀 처리 되지 않습니다 .
d512

1
이 웹 사이트에 더 많은 답변이 평신도를 위해 작성 되었으면합니다 ... 'next ()는 인수없이 "농담입니다. 실제로 처리하고 싶지 않습니다."라고 말합니다.-멍청한 사람에게 적합합니다 ... (@ d512에는 그래도 더 나은 설명)
daCoda

129

대부분의 프레임 워크에서 요청을 받고 응답을 반환하려고합니다. Node.js의 비동기 특성 때문에 사소한 작업을 수행하는 경우 중첩 된 콜백에 문제가 발생합니다. 이 문제가 발생하지 않도록 Connect.js (v4.0 이전에는 Express.js가 connect.js 위에있는 레이어였습니다)에는 2, 3 또는 4 개의 매개 변수가있는 함수 인 미들웨어라는 것이 있습니다.

function (<err>, req, res, next) {}

Express.js 앱은 이러한 기능의 스택입니다.

여기에 이미지 설명 입력

라우터는 특별합니다. 특정 URL에 대해 하나 이상의 미들웨어를 실행할 수있는 미들웨어입니다. 그래서 그것은 스택 내부의 스택입니다.

그럼 다음은 무엇을합니까? 간단합니다. 앱에 다음 미들웨어를 실행하도록 지시합니다. 하지만 다음에 무언가를 전달하면 어떻게됩니까? Express는 현재 스택을 중단하고 4 개의 매개 변수가있는 모든 미들웨어를 실행합니다.

function (err, req, res, next) {}

이 미들웨어는 오류를 처리하는 데 사용됩니다. 나는 다음을하고 싶다 :

next({ type: 'database', error: 'datacenter blew up' });

이 오류로 인해 사용자에게 문제가 있음을 알리고 실제 오류를 기록합니다.

function (err, req, res, next) {
   if (err.type === 'database') {
     res.send('Something went wrong user');
     console.log(err.error);
   }
};

Express.js 애플리케이션을 스택으로 생각한다면 아마도 많은 이상한 점을 직접 해결할 수있을 것입니다. 예를 들어 라우터 후 쿠키 미들웨어를 추가하면 경로에 쿠키가 없다는 것이 이해가됩니다.


3
이 익명 로깅 기능을 어디에 저장 하시겠습니까?
dennismonsewicz 2014 년

"Express는 현재 스택을 중단하고 4 개의 매개 변수가있는 모든 미들웨어를 실행합니다." Express가 정확한 오류 처리기 미들웨어를 어떻게 실행할 수 있는지 궁금합니다. 감사!
Abhishek Agarwal

75

IMHO,이 질문에 대한 대답은 실제로 정확하지 않습니다. 다른 사람들이 말했듯이 실제로는 체인의 다음 핸들러가 실행되는시기를 제어하는 ​​것입니다. 하지만 좀 더 구체적인 코드를 제공하고 싶었습니다. 다음과 같은 간단한 익스프레스 앱이 있다고 가정 해 보겠습니다.

var express = require('express');
var app = express();

app.get('/user/:id', function (req, res, next) {
    console.log('before request handler');
    next();
});

app.get('/user/:id', function (req, res, next) {
    console.log('handling request');
    res.sendStatus(200);
    next();
});

app.get('/user/:id', function (req, res, next) {
    console.log('after request handler');
    next();
});

app.listen(3000, function () {
    console.log('Example app listening on port 3000!')
});

만약 당신이

curl http://localhost:3000/user/123

콘솔에 인쇄 된 것을 볼 수 있습니다.

before request handler
handling request
after request handler

이제 다음 next()과 같이 중간 핸들러에서 호출을 주석 처리하면 :

app.get('/user/:id', function (req, res, next) {
    console.log('handling request');
    res.sendStatus(200);
    //next();
});

콘솔에 다음이 표시됩니다.

before request handler
handling request

마지막 핸들러 (를 인쇄하는 핸들러 after request handler)는 실행되지 않습니다. 더 이상 Express에 다음 핸들러를 실행하도록 지시하지 않기 때문입니다.

따라서 "주"처리기 (200을 반환하는 처리기)가 성공했는지 여부는 중요하지 않습니다. 나머지 미들웨어를 실행하려면을 호출해야합니다 next().

이것이 언제 유용할까요? 요청의 성공 여부에 관계없이 일부 데이터베이스에 들어온 모든 요청을 기록하려고한다고 가정 해 보겠습니다.

app.get('/user/:id', function (req, res, next) {
    try {
       // ...
    }
    catch (ex) {
       // ...
    }
    finally {
       // go to the next handler regardless of what happened in this one
       next();
    }
});

app.get('/user/:id', function (req, res, next) {
    logToDatabase(req);
    next();
});

두 번째 핸들러를 실행 next()하려면 첫 번째 핸들러 를 호출해야 합니다.

노드는 비동기이므로 첫 번째 핸들러의 콜백이 언제 완료되었는지 알 수 없습니다. 을 (를) 호출하여 알려야합니다 next().


Sonfar는 나를위한 최고의 대답입니다.
Norayr Ghukasyan

잘 설명!
Chang

7

매개 변수가없는 next ()는 다음 경로 핸들러 또는 프레임 워크의 다음 미들웨어를 호출합니다.


2
또는 다음 미들웨어.
robertklep

1

단순히 다음 핸들러에 제어를 전달하는 것을 의미합니다.

건배


1

위의 next () 호출에 주목하십시오. 이 함수를 호출하면 앱에서 다음 미들웨어 함수가 호출됩니다. next () 함수는 Node.js 또는 Express API의 일부가 아니지만 미들웨어 함수에 전달되는 세 번째 인수입니다. next () 함수는 무엇이든 명명 할 수 있지만 규칙에 따라 항상 "next"로 명명됩니다. 혼동을 피하기 위해 항상이 규칙을 사용하십시오.


0

질문은 지금까지 제공된 답변에서 일주일에 다뤄지는 것 같은 next ( 'route') 사용에 대해서도 질문했습니다.

  1. next () 사용법 :

간단히 말해서 다음 미들웨어 기능입니다.

이 공식 Express JS 문서- '미들웨어 작성'페이지 에서 발췌 :

"미들웨어 함수 myLogger는 단순히 메시지를 인쇄 한 다음 next () 함수를 호출하여 스택 의 다음 미들웨어 함수 로 요청을 전달 합니다."

var express = require('express')
var app = express()

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

Express JS 문서의이 페이지 에서는 "현재 미들웨어 함수가 요청-응답주기를 종료하지 않으면 next ()를 호출하여 다음 미들웨어 함수에 제어를 전달해야합니다. 그렇지 않으면 요청이 중단됩니다."라고 설명합니다.

  1. next ( 'route') 사용법 :

간단히 말해서 : 다음 경로 (vs. next ()의 경우 다음 미들웨어 함수 )

Express JS 문서 에서 추출 - '미들웨어 사용'페이지 :

"라우터 미들웨어 스택에서 나머지 미들웨어 기능을 건너 뛰려면 next ( 'route')를 호출하여 다음 경로로 제어를 전달하십시오 . 참고 : next ( 'route')는 다음을 사용하여로드 된 미들웨어 기능에서만 작동합니다. app.METHOD () 또는 router.METHOD () 함수.

이 예는 / user / : id 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택을 보여줍니다. "

app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route
  if (req.params.id === '0') next('route')
  // otherwise pass the control to the next middleware function in this stack
  else next()
}, function (req, res, next) {
  // render a regular page
  res.render('regular')
})

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
  res.render('special')
})

0

next () 는 req가있는 미들웨어 함수에 대한 콜백 인수이고, res는 아래 코드에서 next에 대한 http 요청 및 응답 인수입니다.

app.get ( '/', (req, res, next) => {next ()});

그래서 next ()는 전달 된 미들웨어 함수를 호출합니다. 현재 미들웨어 함수가 요청-응답주기를 종료하지 않으면 next ()를 호출해야합니다. 그렇지 않으면 요청이 중단 된 상태로 유지되고 시간이 초과됩니다.

next () fn은 여러 미들웨어 함수가 app.use 또는 app.METHOD에 전달 될 때 각 미들웨어 함수 내에서 호출되어야합니다 . 그렇지 않으면 다음 미들웨어 함수가 호출되지 않습니다 (미들웨어 함수가 둘 이상 전달되는 경우). 나머지 미들웨어 함수 호출을 건너 뛰려면 미들웨어 함수 내에서 next ( 'route')를 호출 한 후 다른 미들웨어 함수를 호출하지 않아야합니다. 아래 코드에서는 fn1 내에서 next ()가 호출되므로 fn1이 호출되고 fn2도 호출됩니다. 그러나 fn2 내에서 next ( 'route')가 호출되므로 fn3은 호출되지 않습니다.

app.get('/fetch', function fn1(req, res, next)  {
console.log("First middleware function called"); 
    next();
}, 
function fn2(req, res, next) {
    console.log("Second middleware function called"); 
    next("route");
}, 
function fn3(req, res, next) {
    console.log("Third middleware function will not be called"); 
    next();
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.