찾다
웹 프론트엔드JS 튜토리얼Node.js의 타이머 이해

Node.js의 타이머 이해

Dec 03, 2020 pm 06:11 PM
node.js시간제 노동자

Node.js의 타이머 이해

관련 추천: "node js tutorial"

timer는 미래의 특정 시점에 호출될 함수를 예약하는 데 사용됩니다. Node.js의 타이머 함수는 Node.js에서 제공하는 타이머 API를 구현합니다. 웹 브라우저 유사한 API이지만 이벤트 루프 구현을 사용하면 Node.js에 4개의 관련 메소드가 있습니다

  • setTimeout(callback, Delay[, ...args])

  • setInterval(callback[, ... args ])

  • setImmediate(callback[, ...args])

  • process.nextTick(callback[, ...args])

처음 두 가지 의미는 웹의 의미와 일치합니다. 마지막 두 가지는 Node.js에 고유한 것으로, 효과는 setTimeout(callback, 0)인 것 같습니다. 이는 Node.js 프로그래밍에서 가장 많이 사용됩니다

Node.js는 콜백이 트리거되는 정확한 시간을 보장하지 않으며, 그렇지도 않습니다. 순서가 보장되면 콜백은 지정된 시간에 최대한 가깝게 호출됩니다. setTimeout 지연이 2147483647보다 크거나 1보다 작으면 지연은 1로 설정되고 정수가 아닌 지연은 정수로 잘립니다.

이상한 실행 순서

몇 가지 방법을 사용하여 비동기적으로 인쇄하는 예를 살펴보세요. number

setImmediate(console.log, 1);
setTimeout(console.log, 1, 2);
Promise.resolve(3).then(console.log);
process.nextTick(console.log, 4);
console.log(5);

는 5 4 3 2 1 또는 5 4 3 1 2

동기식 및 비동기식

을 인쇄합니다. 다섯 번째 줄은 동기식 실행이고 나머지는 비동기식입니다

setImmediate(console.log, 1);
setTimeout(console.log, 1, 2);
Promise.resolve(3).then(console.log);
process.nextTick(console.log, 4);
/****************** 同步任务和异步任务的分割线 ********************/
console.log(5);

그러므로 5를 먼저 인쇄하면 이해하기 쉽습니다. 나머지는 모두 비동기 작업입니다. Node.js는 어떤 순서로 작업을 실행하나요?

event loop

Node.js는 시작 후 이벤트 폴링을 초기화합니다. 그 과정에서 비동기 호출, 타이머 예약 및 process.nextTick()을 처리한 다음 이벤트 루프 처리를 시작할 수 있습니다. 공식 홈페이지에 이벤트 루프 동작 순서를 소개하는 그림이 있습니다

┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<p>이벤트 루프의 각 단계에는 작업 대기열이 있습니다. 이벤트 루프가 특정 단계에 진입하면 해당 단계의 작업 대기열이 다음 단계까지 실행됩니다. 또는 실행된 콜백이 시스템 상한에 도달하면 다음 단계로 이동합니다. 모든 단계가 순차적으로 실행되면 이벤트 루프가 틱을 완료했다고 합니다</p><p>비동기 작업은 다음 단계에 배치됩니다. 이벤트 루프 틱, 프로세스.nextTick은 다음 이벤트 루프 틱에 들어가기 전에 실행되므로 다른 비동기 작업보다 먼저 실행되어야 합니다</p><pre class="brush:php;toolbar:false">setImmediate(console.log, 1);
setTimeout(console.log, 1, 2);
Promise.resolve(3).then(console.log);
/****************** 下次 event loop tick 分割线 ********************/
process.nextTick(console.log, 4);
/****************** 同步任务和异步任务的分割线 ********************/
console.log(5);

각 단계의 주요 작업

  • timers: setTimeout, setInterval 콜백 실행

  • pending callbacks: 실행 I/O(파일, 네트워크 등) callback

  • idle, prepare: 시스템 내부에서만 호출

  • poll: 새 I/O 이벤트 가져오기, 실행 관련 콜백을 처리하고 적절한 조건에서 노드를 차단합니다.

  • check: 이 단계에서 setImmediate 콜백이 실행됩니다.

  • close callbacks: 소켓 등의 종료 이벤트 콜백을 실행합니다.

대부분 일일 개발의 비동기 작업은 타이머, 폴링, 단계 처리 확인에서 수행됩니다.

timers

Node.js는 타이머 단계에 만료된 타이머가 있는지 확인합니다. 만료된 타이머가 있는 경우 콜백은 다음과 같습니다. 실행을 기다리기 위해 타이머 대기열에 배치됩니다. Node.js는 단일 스레드를 사용하며 시스템의 상황 및 기타 프로세스에 따라 타이머가 실행된다는 보장이 없습니다. 정확한 시간에는 두 가지 주요 유형의 타이머가 있습니다.

  • Immediate

  • Timeout

Immediate 유형 타이머 콜백은

check 단계에서 호출되며, Timeout 타이머는 즉시 콜백을 호출합니다. 설정된 시간이 지난 후에는 가능하지만 여러 번 실행하면 I/O를 차단하고 폴링하는 시간이 달라지는 것을 알 수 있습니다


그러면 폴 큐에 있는 이벤트를 처리합니다

이벤트 루프가 폴 단계에 진입하고 예약된 타이머가 없는 경우

  • 폴 큐가 비어 있지 않으면 이벤트 루프는 콜백 큐를 반복하고 큐가 소진되거나 시스템에 도달할 때까지 동기적으로 실행됩니다. 최대 콜백 수에 도달

    폴 큐가 비어 있는 경우
  • setImmediate() 작업이 있는 경우 이벤트 루프는 폴

    단계에서 종료됩니다.

    check
  • 단계에 들어간 후

setImmediate( ) 작업, 이벤트 루프는 콜백이 대기열에 추가되기를 기다리는

poll
    단계에서 차단된 다음 즉시 실행됩니다
    • 일단 poll 대기열이 비어 있으면 이벤트 루프는 타이머 큐가 비어 있으면 이벤트 루프의 다음 라운드로 들어갑니다위에서 언급한 것처럼 서로 다른 I/O에 있으면 setTimeout과 setImmediate의 실행 순서를 결정할 수 없지만 setTimeout과 setImmediate가 하나의 I/O에 있으면 실행 순서를 결정할 수 없습니다. /O 콜백에서는 setImmediate() 작업이 poll 단계에서 감지되고, 이벤트 루프가 직접 check 단계에 들어가 setImmediate 콜백을 실행하기 때문에 setImmediate가 먼저 실행되어야 합니다.
    setTimeout(() => {
      console.log('timeout');
    }, 0);
    
    setImmediate(() => {
      console.log('immediate');
    });
  • checksetImmediate 콜백이 실행됩니다. 이 단계에서는
  • 为什么 Promise.then 比 setTimeout 早一些

    前端同学肯定都听说过 micoTask 和 macroTask,Promise.then 属于 microTask,在浏览器环境下 microTask 任务会在每个 macroTask 执行最末端调用

    在 Node.js 环境下 microTask 会在每个阶段完成之间调用,也就是每个阶段执行最后都会执行一下 microTask 队列

setImmediate(console.log, 1);
setTimeout(console.log, 1, 2);
/****************** microTask 分割线 ********************/
Promise.resolve(3).then(console.log); // microTask 分割线
/****************** 下次 event loop tick 分割线 ********************/
process.nextTick(console.log, 4);
/****************** 同步任务和异步任务的分割线 ********************/
console.log(5);

setImmediate VS process.nextTick

setImmediate 听起来是立即执行,process.nextTick 听起来是下一个时钟执行,为什么效果是反过来的?这就要从那段不堪回首的历史讲起

最开始的时候只有 process.nextTick 方法,没有 setImmediate 方法,通过上面的分析可以看出来任何时候调用 process.nextTick(),nextTick 会在 event loop 之前执行,直到 nextTick 队列被清空才会进入到下一 event loop,如果出现 process.nextTick 的递归调用程序没有被正确结束,那么 IO 的回调将没有机会被执行

const fs = require('fs');

fs.readFile('a.txt', (err, data) => {
	console.log('read file task done!');
});

let i = 0;
function test(){
	if(i++ <p>执行程序将返回</p><pre class="brush:php;toolbar:false">nextTick 1
nextTick 2
...
...
nextTick 999999
read file task done!

于是乎需要一个不这么 bug 的调用,setImmediate 方法出现了,比较令人费解的是在 process.nextTick 起错名字的情况下,setImmediate 也用了一个错误的名字以示区分。。。

那么是不是编程中应该杜绝使用  process.nextTick 呢?官方推荐大部分时候应该使用 setImmediate,同时对 process.nextTick 的最大调用堆栈做了限制,但 process.nextTick 的调用机制确实也能为我们解决一些棘手的问题

  • 允许用户在 even tloop 开始之前 处理异常、执行清理任务

  • 允许回调在调用栈 unwind 之后,下次 event loop 开始之前执行

一个类继承了 EventEmitter,而且想在实例化的时候触发一个事件

const EventEmitter = require('events');
const util = require('util');

function MyEmitter() {
  EventEmitter.call(this);
  this.emit('event');
}
util.inherits(MyEmitter, EventEmitter);

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

在构造函数执行 this.emit('event') 会导致事件触发比事件回调函数绑定早,使用 process.nextTick 可以轻松实现预期效果

const EventEmitter = require('events');
const util = require('util');

function MyEmitter() {
  EventEmitter.call(this);

  // use nextTick to emit the event once a handler is assigned
  process.nextTick(() => {
    this.emit('event');
  });
}
util.inherits(MyEmitter, EventEmitter);

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

更多编程相关知识,请访问:编程教学!!

위 내용은 Node.js의 타이머 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 博客园에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
파이썬과 자바 스크립트의 미래 : 트렌드와 예측파이썬과 자바 스크립트의 미래 : 트렌드와 예측Apr 27, 2025 am 12:21 AM

Python 및 JavaScript의 미래 추세에는 다음이 포함됩니다. 1. Python은 과학 컴퓨팅 분야에서의 위치를 ​​통합하고 AI, 2. JavaScript는 웹 기술의 개발을 촉진하고, 3. 교차 플랫폼 개발이 핫한 주제가되고 4. 성능 최적화가 중점을 둘 것입니다. 둘 다 해당 분야에서 응용 프로그램 시나리오를 계속 확장하고 성능이 더 많은 혁신을 일으킬 것입니다.

Python vs. JavaScript : 개발 환경 및 도구Python vs. JavaScript : 개발 환경 및 도구Apr 26, 2025 am 12:09 AM

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

JavaScript가 C로 작성 되었습니까? 증거를 검토합니다JavaScript가 C로 작성 되었습니까? 증거를 검토합니다Apr 25, 2025 am 12:15 AM

예, JavaScript의 엔진 코어는 C로 작성되었습니다. 1) C 언어는 효율적인 성능과 기본 제어를 제공하며, 이는 JavaScript 엔진 개발에 적합합니다. 2) V8 엔진을 예를 들어, 핵심은 C로 작성되며 C의 효율성 및 객체 지향적 특성을 결합하여 C로 작성됩니다.

JavaScript의 역할 : 웹 대화식 및 역동적 인 웹JavaScript의 역할 : 웹 대화식 및 역동적 인 웹Apr 24, 2025 am 12:12 AM

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript : 연결이 설명되었습니다C 및 JavaScript : 연결이 설명되었습니다Apr 23, 2025 am 12:07 AM

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션Apr 22, 2025 am 12:02 AM

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Apr 21, 2025 am 12:01 AM

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.

JavaScript 통역사 및 컴파일러에서 C/C의 역할JavaScript 통역사 및 컴파일러에서 C/C의 역할Apr 20, 2025 am 12:01 AM

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음