"res.send"후에 코드를 실행할 수있는 이유는 무엇입니까?


81

다음 코드의 동작 뒤에있는 메커니즘이 무엇인지 궁금합니다.

res.send(200, { data: 'test data' });
console.log('still here...');

내 이해는 함수를 반환res.send 하지 않지만 연결을 닫거나 요청을 종료한다는 것 입니다. 이것은 명령 후에도 여전히 코드를 실행할 수있는 이유를 설명 할 수 있습니다 (익스프레스 소스를 살펴 봤는데 비동기 함수가 아닌 것 같습니다).res.send

내가 놓칠 수있는 다른 것이 있습니까?


죄송합니다. 귀하의 게시물을 잘못 읽었으며 완벽하게 합법적이므로 귀하의 코드에 문제가 무엇인지 확신 할 수 없었습니다. 호출 send하면 http 연결에서 데이터를 파이프하고 코드가 계속됩니다. return코드를 종료하거나 다른 것을 작성하지 않으려 는 경우 에만 사용할 수 있습니다 . 오해해서 죄송합니다.
Timmerz 2013

답변:


128

물론 endHTTP 응답을 종료하지만 코드에 특별한 작업은 수행하지 않습니다.

응답을 종료 한 후에도 다른 작업을 계속할 수 있습니다.

하지만 할 수없는 것은 res. 응답이 종료되었으므로 더 많은 데이터를 쓸 수 없습니다.

res.send(...);
res.write('more stuff'); // throws an error since res is now closed

이 동작은 HTTP 요청에 스레드를 할당하고 응답이 끝나면 스레드를 종료하는 다른 기존 프레임 워크 (PHP, ASP 등)와는 다릅니다. ASP와 같은 동등한 함수를 호출하면 Response.End스레드가 종료되고 코드 실행이 중지됩니다. 노드에는 중지 할 스레드가 없습니다. reqres(에 통화 방법을 시도하지 않는 한 너무 오래 더 이상 이벤트를 발생하지만 콜백의 코드가 실행 계속 무료로하지 않습니다 res열려 있어야 유효한 응답을 필요로).


8
이 답변은 매우 유용했으며 이념적 인 이유로 nodejs를 떠나도록 설득했습니다.
jkatzer 2014

33
@jkatzer 이데올로기는 약합니다. 실용주의가 이깁니다.
Anatoly G

8
물론 Node는 실행 환경 일 뿐이며 expressjs를 사용하는 경우 이것이 웹 서버임을 기억하십시오. 당신이 말하는 것은 PHP가 응답을 반환 한 후에도 Apache가 계속 실행되는 이유를 궁금해하는 것과 같습니다. 이 추가 용량을 사용하도록 선택하거나 응답을 보낸 후 응답 상태를 기록하거나 다른 응용 프로그램 기능을 수행 할 수 있습니다. 그러나 큰 힘으로 큰 책임이 온다 ...
samazi

11
@jkatzer-귀하의 진술은 전적으로 무모하고 유독 한 사고 방식을 설명합니다.
The Dembinski

1
@AnatolyG 저는이 댓글 섹션을 읽는 동안 당신의 댓글을 적어도 5 번 읽었고, 매번 표절을 읽고, 지금 나 자신에 대해 웃고있었습니다. Lol.
Lalit Fauzdar

44

편집 : 필요가 없을 때 값을 반환해서는 안되므로 아래에 설명 된 작업을 더 이상 수행하지 않습니다. 그것은 당신의 코드를 읽기 어렵게 만들고 엉망진창처럼 보입니다. 대신 return 문을 res.send(). @slavafomin은 의견에서 이것을 잘 설명했습니다.

함수 실행을 중지하고 동시에 응답을 보내는 간단한 방법은 다음을 수행하는 것입니다.

return res.send('500', 'Error message here');

이를 통해 짧은 if문 을 사용 하여 다음과 같은 오류를 처리 할 수 있습니다 .

if (err) {
    return res.send('500', 'Error message here');
}

함수 의 정확한 반환연결을 종료 한 후 연결의 전체 상태 (요청, 상태, 헤더 등) 를 포함 하는 것처럼 보이는 객체 이지만 아무 작업도하지 않을 것이기 때문에 중요하지 않습니다.res.send


2
이것은 좋은 점이지만 기술적으로 답은 아닙니다. 질문은 방법보다는 이유에 관한 것이기 때문입니다. 그럼에도 불구하고 큰 공헌, 따라서 찬성 :).
Nepoxx

3
하지만 당시에는 댓글을 달 수 없어 답변을 게시해야했습니다.
Marcos Pereira 2014

4
이 기술을 사용하지 않는 것이 좋습니다. 그것은 코드를 더 짧게 만들지 만 또한 의미가없고 모호 해져 잘못된 의미를 사용합니다. 함수의 값을 사용하지 않는 경우 하나를 반환하지 않아야합니다. 또한 정적 코드 분석을 사용하여 형식화 된 JavaScript (예 : TypeScript) 및 도구를 손상시킬 수 있습니다. 다른 말로하면, 끔찍하고 비전문적으로 보입니다.
Slava Fomin II

1
@SlavaFominII 다음과 같을 수 있습니다 : res.send('500', 'Error message here');return;내부 if문.
Ali Sherafat

@SlavaFominll 나는이 방법이 너무 일반적이라고 생각하므로 더 이상 hackish라고 부를 수 없습니다. 정적 분석기의 경우-익스프레스 개발자가이 함수의 반환을 처리하는 사람이므로 걱정할 것이별로 없습니다. 특정 문제가 발생 했습니까?
Ohad Cohen

0

가능한 솔루션은이 라이브러리입니다 : 에 마감

var destroy = require('destroy')
var fs = require('fs')
var http = require('http')
var onFinished = require('on-finished')

http.createServer(function onRequest (req, res) {
  var stream = fs.createReadStream('package.json')
  stream.pipe(res)
  onFinished(res, () => {
    destroy(stream)
  })
})

Express 에서도 작동 합니다. 예 :

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

app.get('/video', (req, res) => {
 const ffmpeg = spawn(ffmpegPath, argsArray);
 ffmpeg.stdout.pipe(res);
 onFinished(res, () => {
   ffmpeg.kill();
 });
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.