이 둘의 차이점은 무엇이며 언제 다른 하나를 사용합니까?
답변:
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 콜백과 Check Queue 콜백 후에 호출됩니다. 이벤트 루프로 각 반복에서 먼저 타이머 큐를 처리하므로 어느 것이 먼저 실행 될지는 위상 이벤트 루프가 무엇인지에 따라 달라집니다.
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콜백 에서 호출되는 경우를 제외하고 거의 항상 이전 에 실행 됩니다 .
setTimeout와, 이동-에 있어야합니다 setImmediate필요하다고 표시된 경우에만 사용.
제공된 답변에 완전히 만족하지 않습니다. 더 나은 답변이라고 생각하는 내용을 여기에 게시했습니다. https://stackoverflow.com/a/56724489/5992714
질문은 주 모듈에서 사용할 때 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를 사용할 때 브라우저가 멈출 수 있습니다.