ProgramingTip

NodeJS-setTimeout (fn, 0) 대 setImmediate (fn)

bestdevel 2020. 11. 5. 08:26
반응형

NodeJS-setTimeout (fn, 0) 대 setImmediate (fn)


이 둘의 차이점은 무엇이며 언제 다른 하나를 사용합니까?


setTimeout 은 지연이 많은 함수를 호출 할 것입니다. 함수가 호출 될 때마다 즉시 실행되지 않고 모든 실행 및 현재 대기중인 이벤트가 실행되고 실행 대기합니다. setTimeout (, 0)은 내부적으로 현재 큐의 모든 현재 함수가 실행 된 후 실행됨을 의미합니다. 시간이 얼마나 걸릴지 보장 할 수 없습니다.

setImmediate 는 함수 를 사용하지 않는다는 점을 제외하면 이와 유사합니다. I / O 이벤트의 큐를 확인합니다. 현재 스냅 샷의 모든 I / O 이벤트가 처리됩니다. process.nextTick과 사건하게 마지막 I / O 처리기 독점에 큐에 넣습니다. 그래서 더 빠 사용합니다.

또한 (setTimeout, 0)은 실행하기 전에 한 번 타이머를 확인 느려 처리합니다. 어디에 두 배로 느려질 수 있습니다. 다음은 벤치 마크입니다.

var Suite = require('benchmark').Suite
var fs = require('fs')

var suite = new Suite

suite.add('deffered.resolve()', function(deferred) {
  deferred.resolve()
}, {defer: true})

suite.add('setImmediate()', function(deferred) {
  setImmediate(function() {
    deferred.resolve()
  })
}, {defer: true})

suite.add('setTimeout(,0)', function(deferred) {
  setTimeout(function() {
    deferred.resolve()
  },0)
}, {defer: true})

suite
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run({async: true})

많이

deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled)
setImmediate() x 914 ops/sec ±2.48% (57 runs sampled)
setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)

첫 번째는 가능한 가장 빠른 통화에 대한 아이디어를 제공합니다. setTimeout이 다른 것보다 절반으로 호출 할 수 있습니다. 또한 setImmediate는 파일 시스템 호출에 맞게 조정됩니다. 따라서 부하가 걸리면 성능이 두 번 빠집니다. 나는 setTimeout이 더 잘 할 수있는 생각하지 않습니다.

setTimeout은 잠시 후 함수를 호출하는 방해가되지 않는 방법입니다. 브라우저에서와 똑같습니다. 서버 측에서는 적합하지 않을 수 있습니다 (setTimeout이 아닌 Benchmark.js를 사용하는 이유를 생각해보십시오).


이벤트 루프의 작동 방식에 대한 훌륭한 기사이며 오해를 해소합니다. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/

기사 인용 :

setImmediateI / O 예약이 완료됩니다. setImmediate I / O Queue 이후에 처리되는 Check Queue에 배치됩니다.

setTimeout(fn, 0)Timer Queue에 배치 완료 I / O 연속 호출됩니다. 이벤트 루프로 각 반복에서 먼저 타이머 큐를 처리하는 것이 어느 것이 먼저 실행 될지 루프가 무엇인지에 따라 달라집니다.


setImmediate () 는 I / O 이벤트 후입니다 setTimeout 및 setInterval 이전에 빠른 실행 인 실행을 예약합니다.

setTimeout () 은 지연 밀리 초 나중에 일회성 예약 실행을 예약하는 것입니다.

이 문서가 말하는 것입니다.

setTimeout(function() {
  console.log('setTimeout')
}, 0)

setImmediate(function() {
  console.log('setImmediate')
})

위의 코드를 실행하면 결과는 다음과 달라집니다. 현재 문서에 "I / O 이벤트 후, setTimeout 및 setInterval 이전에 예약의"즉시 "실행을 예약 예측"이라고 명시되어 있습니다. ..

결과 ..

setTimeout

setImmediate

예제를 다른 타이머로 래핑하면 항상 setImmediate 다음에 setTimeout이 인쇄됩니다.

setTimeout(function() {
  setTimeout(function() {
    console.log('setTimeout')
  }, 0);
  setImmediate(function() {
    console.log('setImmediate')
  });
}, 10);

setImmediate당신이 정말로 필요하다고 확신하지 않는 한 항상을 사용 하십시오 setTimeout(,0)(그러나 나는 상상조차 할 수 없습니다, 무엇을 위해). setImmediate콜백은 setTimeout(,0)첫 번째 틱 및 setImmediate콜백 에서 호출되는 경우를 제외하고 거의 항상 이전 실행 됩니다 .


Navya S 의 대답이 올바르지 않다고 생각합니다 . 여기 내 테스트 코드가 있습니다.

let set = new Set();

function orderTest() {
  let seq = [];
  let add = () => set.add(seq.join());
  setTimeout(function () {
    setTimeout(function () {
      seq.push('setTimeout');
      if (seq.length === 2) add();
    }, 0);

    setImmediate(function () {
      seq.push('setImmediate');
      if (seq.length === 2) add();
    });
  }, 10);
}

// loop 100 times
for (let i = 0; i < 100; i++) {
  orderTest();
}

setTimeout(() => {
  // will print one or two items, it's random
  for (item of set) {
    console.log(item);
  }
}, 100);

설명은 여기


setTimeout (fn, 0)은 대규모 업데이트에서 브라우저가 중단되는 것을 방지하는 데 사용할 수 있습니다. 예를 들어 websocket.onmessage에서 html 변경이있을 수 있으며 메시지가 계속 오면 setImmidiate를 사용할 때 브라우저가 멈출 수 있습니다.


제공된 답변에 완전히 만족하지 않습니다. 더 나은 답변이라고 생각하는 내용을 여기에 게시했습니다. https://stackoverflow.com/a/56724489/5992714

질문은 주 모듈에서 사용될 때 setTimeout (0) 및 setImmediate ()의 동작이 정의되지 않은 이유는 무엇입니까?


이벤트 루프를 차단하지 않으려면 setImmediate ()를 사용하십시오. 콜백은 현재 이벤트가 완료되는 즉시 다음 이벤트 루프에서 실행됩니다.

지연을 제어하려면 setTimeout ()을 사용하십시오. 이 기능은 지정된 지연 후에 실행됩니다. 최소 지연은 1 밀리 초입니다.

참고 URL : https://stackoverflow.com/questions/24117267/nodejs-settimeoutfn-0-vs-setimmediatefn

반응형