노드 타이머
엔진 이외 의 기능 만 사용 하면 외부 와 상호작용 을 하여 비동기 조작 을 형성 해 야 한다.비동기 동작 이 너무 많아 서 자바 스 크 립 트 는 비동기 문법 을 많이 제공 해 야 합 니 다.이것 은 마치 어떤 사람들 이 늘 타격 을 받 는 것 과 같다.그의 타격 저항 능력 은 반드시 매우 강해 져 야 한다.그렇지 않 으 면 그 는 끝장 이다.
Node 의 비동기 문법 은 브 라 우 저 보다 더 복잡 합 니 다.커 널 과 대화 할 수 있 기 때문에 전문 적 인 라 이브 러 리 libuv 를 만들어 야 합 니 다.이 라 이브 러 리 는 각종 반전 함수 의 실행 시간 을 책임 집 니 다.비동기 임 무 는 마지막 에 메 인 스 레 드 로 돌아 가 하나씩 줄 을 서서 실행 해 야 하기 때 문 입 니 다.
비동기 임 무 를 조율 하기 위해 노드 는 네 개의 타 이 머 를 제공 하여 임 무 를 지정 한 시간 에 실행 할 수 있 도록 했다.
당신 은 아래 코드 의 운행 결 과 를 말 할 수 있 습 니까?
// test.js
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
process.nextTick(() => console.log(3));
Promise.resolve().then(() => console.log(4));
(() => console.log(5))();
운행 결 과 는 다음 과 같다.$ node test.js
만약 네가 한 마디 로 옳다 고 말 할 수 있다 면 더 이상 볼 필요 가 없 을 것 이다.본 고 는 Node 가 각종 타 이 머 를 어떻게 처리 하 는 지,아니면 libuv 라 이브 러 리 가 어떻게 비동기 임 무 를 메 인 스 레 드 에서 수행 하 는 지 상세 하 게 설명 한다.1.동기 화 작업 과 비동기 작업
우선 동기 화 작업 은 항상 비동기 작업 보다 일찍 실 행 됩 니 다.
앞의 코드 는 마지막 줄 만 동기 화 작업 이기 때문에 가장 먼저 실 행 됩 니 다.
(() => console.log(5))();
2.이번 순환 과 2 차 순환비동기 임 무 는 두 가지 로 나 눌 수 있다.
이번 라운드 에서 순환 하 는 비동기 퀘 스 트 추가
순환 하 는 비동기 퀘 스 트 추가
'순환'이란 이벤트 순환(event loop)을 말한다.이것 은 JavaScript 엔진 이 비동기 작업 을 처리 하 는 방식 입 니 다.나중에 자세히 설명 하 겠 습 니 다.여기 서 이해 하기 만 하면 이번 순환 은 반드시 다음 순환 보다 일찍 실행 하면 된다.
Node 는 process.nextTick 과 Promise 의 리 셋 함 수 를 이번 라운드 순환 에 추가 하도록 규정 하고 있 습 니 다.즉,동기 화 작업 이 완료 되면 실행 을 시작 합 니 다.한편,setTimeout,setInterval,setImmediate 의 리 셋 함 수 는 차 순환 에 추 가 됩 니 다.
즉,문장의 첫 번 째 줄 과 네 번 째 줄 은 반드시 첫 번 째 줄 과 두 번 째 줄 보다 일찍 실 행 될 것 이다.
// ,
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
// ,
process.nextTick(() => console.log(3));
Promise.resolve().then(() => console.log(4));
3.process.nextTick()process.nextTick 이라는 이름 은 약간 오도 되 었 습 니 다.이것 은 이번 라운드 에서 순환 적 으로 실 행 된 것 이 고 모든 비동기 작업 에서 가장 빨리 실 행 된 것 입 니 다.
Node 는 모든 동기 화 작업 을 수행 하고 process.nextTick 의 작업 대기 열 을 수행 합 니 다.그래서 다음 줄 코드 는 두 번 째 출력 결과 입 니 다.
process.nextTick(() => console.log(3));
기본적으로 비동기 임 무 를 가능 한 한 빨리 수행 하고 싶다 면 process.nextTick 을 사용 하 세 요.4.작은 임무
언어 규격 에 따라
Promise
대상 의 반전 함수 가 비동기 작업 의'마이크로 작업'microtask
대기 열 에 들 어 갑 니 다.마이크로 퀘 스 트 대기 열 은
process.nextTick
대기 열 뒤에 추가 되 며,이번 라운드 순환 에 도 속한다.그래서 아래 코드 는 항상 3 을 먼저 출력 하고 4 를 출력 합 니 다.
process.nextTick(() => console.log(3));
Promise.resolve().then(() => console.log(4));
// 3
// 4
이전 대기 열 이 모두 비 워 져 야 다음 대기 열 이 실 행 됩 니 다.
process.nextTick(() => console.log(1));
Promise.resolve().then(() => console.log(2));
process.nextTick(() => console.log(3));
Promise.resolve().then(() => console.log(4));
// 1
// 3
// 2
// 4
위의 코드 에서 모든process.nextTick
의 리 턴 함수 가Promise
보다 일찍 실 행 될 것 입 니 다.이로써 이번 순환 의 집행 순 서 는 끝났다.
process.nextTick()
5.사건 순환 의 개념다음은 다음 순환 의 실행 순 서 를 소개 합 니 다.이벤트 순환(event loop)이 무엇 인지 이해 해 야 합 니 다.
노드 의공식 문서는 이렇게 소개 했다.
“When Node.js starts, it initializes the event loop, processes the provided input script which may make async API calls, schedule timers, or call process.nextTick(), then begins processing the event loop.”
이 단락 의 말 은 매우 중요 하 니 자세히 읽 어야 한다.그것 은 세 가지 의 미 를 표현 했다.
우선,어떤 사람들 은 메 인 스 레 드 를 제외 하고 단독 이벤트 순환 스 레 드 가 존재 한다 고 생각한다.그렇지 않 습 니 다.메 인 스 레 드 만 있 고 이벤트 순환 은 메 인 스 레 드 에서 이 루어 집 니 다.
그 다음 에 Node 가 스 크 립 트 를 실행 하기 시 작 했 을 때 이벤트 순환 을 초기 화 합 니 다.그러나 이 때 는 이벤트 순환 이 시작 되 지 않 았 고 다음 일 을 먼저 완성 합 니 다.
마지막 으로 위의 이 일 들 을 모두 끝내 고 사건 의 순환 이 본 격 적 으로 시작 되 었 다.
6.사건 순환 의 6 단계
사건 의 순환 은 무한 정 실 행 될 것 이 며,한 차례 또 한 차례 실 행 될 것 이다.비동기 작업 의 리 셋 함수 대기 열 이 비어 있어 야 실행 을 중단 할 수 있 습 니 다.
매 라운드 의 사건 순환 은 6 단계 로 나 뉜 다.이 단계 들 은 순서대로 실 행 될 것 이다.
timers
I/O callbacks
idle, prepare
poll
check
close callbacks
단계 마다 먼저 나 온 리 턴 함수 대기 열 이 있 습 니 다.한 단계 의 리 턴 함수 대기 열 이 비 워 졌 습 니 다.실행 할 리 턴 함수 가 모두 실행 되 어야 이벤트 순환 이 다음 단계 에 들 어 갈 수 있 습 니 다.
다음은 각 단계 의 의 미 를 간단하게 소개 하고 공식 문 서 를 볼 수 있 으 며 libuv 의 소스 코드 해석 도 참고 할 수 있 습 니 다.
(1)timers
이것 은 타이머 단계 입 니 다.setTimeout()과 setInterval()을 처리 하 는 리 셋 함수 입 니 다.이 단계 에 들 어가 면 메 인 스 레 드 는 현재 시간,타이머 의 조건 을 만족 시 키 는 지 확인 합 니 다.만족 하면 리 셋 함 수 를 실행 합 니 다.그렇지 않 으 면 이 단 계 를 떠 납 니 다.
(2)I/O callbacks
다음 작업 의 리 셋 함 수 를 제외 하고 다른 리 셋 함 수 는 모두 이 단계 에서 실 행 됩 니 다.
이 단 계 는 libuv 내부 호출 만 가능 합 니 다.무시 할 수 있 습 니 다.
(4)Poll
이 단 계 는 폴 링 시간 으로 아직 돌아 오지 않 은 I/O 이 벤트 를 기다 리 는 데 사 용 됩 니 다.예 를 들 어 서버 의 응답,사용자 가 마 우 스 를 이동 하 는 등 입 니 다.
이 단계 의 시간 은 비교적 길 것 이다.다른 비동기 작업(예 를 들 어 만 료 된 타이머)이 없 으 면 이 단계 에 머 물 러 I/O 요청 이 결 과 를 되 돌려 주 기 를 기다 릴 것 입 니 다.
(5)check
이 단 계 는 setImmediate()의 반전 함 수 를 실행 합 니 다.
(6)close callbacks
이 단 계 는 닫 기 요청 의 반전 함 수 를 실행 합 니 다.예 를 들 어
socket.on('close', ...)
.7.사건 순환 의 예시
다음은 공식 문서 에서 온 예시 이다.
const fs = require('fs');
const timeoutScheduled = Date.now();
// :100ms
setTimeout(() => {
const delay = Date.now() - timeoutScheduled;
console.log(`${delay}ms`);
}, 100);
// : 200ms
fs.readFile('test.js', () => {
const startCallback = Date.now();
while (Date.now() - startCallback < 200) {
//
}
});
위의 코드 는 두 개의 비동기 작업 이 있 습 니 다.하 나 는 100 ms 이후 에 실 행 된 타이머 이 고 하 나 는 최소 200 ms 의 파일 을 읽 어야 합 니 다.운행 결 과 는 무엇 입 니까?스 크 립 트 가 1 차 이벤트 순환 에 들 어간 후 만 료 된 타이머 도 없고 이미 실행 할 수 있 는 I/O 리 셋 함수 도 없 기 때문에 폴 단계 에 들 어가 서 커 널 이 파일 에서 읽 은 결 과 를 되 돌려 줄 때 까지 기 다 립 니 다.작은 파일 을 읽 는 것 은 일반적으로 100 ms 를 넘 지 않 기 때문에 타이머 가 만 료 되 기 전에 Poll 단계 에서 결 과 를 얻 을 수 있 기 때문에 계속 아래로 실 행 됩 니 다.
2 차 이벤트 순환 은 만 료 된 타이머 가 없 지만 실행 가능 한 I/O 리 셋 함수 가 있 기 때문에 I/O callbacks 단계 에 들 어가 fs.readFile 의 리 셋 함 수 를 실행 합 니 다.이 반전 함 수 는 200 ms 가 필요 하 다.즉,그것 이 절반 까지 실 행 될 때 100 ms 의 타이머 가 만 료 된다 는 것 이다.그러나 이 반전 함수 가 실 행 될 때 까지 기 다 려 야 이 단 계 를 떠 날 수 있 습 니 다.
3 차 이벤트 순환 은 만 료 된 타이머 가 있 기 때문에 timers 단계 에서 타 이 머 를 실행 합 니 다.마지막 출력 결 과 는 대략 200 여 밀리초 이다.
8.setTimeout 과 setImmediate
setTimeout
timers 단계 에서 실행 되 기 때문에setImmediate
check 단계 에서 실 행 됩 니 다.그래서 setTimeout 은 setImmediate 보다 일찍 완 성 됩 니 다.
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
위의 코드 는 먼저 1 을 출력 하고 2 를 출력 해 야 하지만 실제 실행 할 때 결 과 는 확실 하지 않 고 때로는 2 를 먼저 출력 하고 1 을 출력 하기 도 한다.이것 은 setTimeout 의 두 번 째 매개 변 수 는 기본적으로 0 이기 때문이다.그러나 실제 노드 는 0 밀리초 도 되 지 않 고 최소 1 밀리초 가 필요 하 다.공식 문서 에 따 르 면 두 번 째 매개 변수의 수치 범 위 는 1 밀리초 에서 2147483647 밀리초 사이 이다.즉,
setTimeout(f, 0)
은setTimeout(f, 1)
과 같다.실제 실 행 될 때 이벤트 순환 에 들 어가 면 1 밀리초 가 될 수도 있 고 1 밀리초 가 안 될 수도 있 으 며 시스템 당시 상황 에 달 려 있다.1 밀리초 가 되 지 않 으 면 timers 단 계 는 건 너 뛰 고 check 단계 에 들 어가 setImmediate 의 리 셋 함 수 를 먼저 실행 합 니 다.
그러나 아래 코드 는 반드시 2 를 먼저 출력 하고 1 을 출력 해 야 한다.
const fs = require('fs');
fs.readFile('test.js', () => {
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
});
위의 코드 는 I/O callbacks 단계 에 들 어가 고 check 단계 이 며 마지막 이 timers 단계 입 니 다.따라서 setImmediate 는 setTimeout 보다 일찍 실 행 됩 니 다.총결산
위 에서 말씀 드 린 것 은 편집장 님 께 서 소개 해 주신 Node 타이머 에 관 한 지식 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Express.js에서 오류를 처리하는 간단한 방법Express에서 오류를 처리하는 여러 가지 방법이 있습니다. 이를 수행하는 일반적인 방법은 기본 익스프레스 미들웨어를 사용하는 것입니다. 또 다른 방법은 컨트롤러 내부의 오류를 처리하는 것입니다. 이러한 처리 방식...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.