js 0 ms 지연 타이머 구현 몇 가지 방식
(function() {
var timeouts = [];
var messageName = "zero-timeout-message";
// Like setTimeout, but only takes a function argument. There's
// no time argument (always zero) and no arguments (you have to use a closure)
function setZeroTimeout(fn) {
timeouts.push(fn);
window.postMessage(messageName, "*");
}
function handleMessage(event) {
if (event.source == window && event.data == messageName) {
event.stopPropagation();
if (timeouts.length > 0) {
var fn = timeouts.shift();
fn();
}
}
}
window.addEventListener("message", handleMessage, true);
// Add the one thing we want added to the window object.
window.setZeroTimeout = setZeroTimeout;
})();
저 자 는 또한 demo 페이지[3]를 제공 하여 setTimeout(0)과 비교 하여 제 브 라 우 저의 실행 결 과 는 다음 과 같 습 니 다.100 iterations of setZeroTimeout took 15 milliseconds.
100 iterations of setTimeout(0) took 488 milliseconds.
결과 에 따 르 면 setZero Timeout 의 집행 은 setTimeout 보다 백 배 나 빨 라 졌 고 이것 은 큰 향상 이 었 다.오늘 토론 하고 자 하 는 것 은 상술 한 방식 을 제외 하고 어떤 방식 으로 0 ms 지연 의 타 이 머 를 실현 할 수 있 는 지 하 는 것 입 니 다.우선,우 리 는 우리 가 사용자 정의 타 이 머 는 비동기 적 이 고,그 다음은 가능 한 한 빨리 실 행 될 수 있 는 지 확인 해 야 합 니 다.비동기 로 말하자면 js 는 여러 가지 해결 방안 을 제 공 했 기 때문에 우 리 는 하나하나 검증 할 수 있다.
여러 가지 실현 방식 을 깊이 토론 하기 전에 제 공 된 setTimeout 비교 버 전 은 다음 과 같 습 니 다.그 다음 에 사용자 정의 실현 방안 은 모두 setTimeout 버 전의 실행 시간 과 비교 되 고 코드 는 비교적 간단 합 니 다.
(function() {
let i = 0;
const start = Date.now();
function test() {
if(i++ < 100) {
setTimeout(test);
} else {
console.log('setTimeout :', Date.now() - start);
}
}
setTimeout(test);
})();
queueMicrotaskquueMicrotask 라 는 api 는 마이크로 작업 을 추가 할 수 있 습 니 다.사용 이 비교적 간단 하고 리 셋 함 수 를 직접 전달 하면 됩 니 다.구체 적 으로 다음 과 같 습 니 다.
(function() {
function setZeroTimeout(fn) {
queueMicrotask(fn);
}
let i = 0;
const start = Date.now();
function test() {
if(i++ < 100) {
setZeroTimeout(test);
} else {
console.log('setZeroTimeout :', Date.now() - start);
}
}
setZeroTimeout(test);
})();
setTimeout 버 전과 비교 한 결과 다음 과 같 습 니 다.setZeroTimeout 실행 시간:2
setTimeout 실행 시간:490
이 API 에 대한 소 개 는 MDN 에 상세 한 설명 이 있 으 면 소 개 를 하지 않 습 니 다.여기 서 한 가지 더 말씀 드 리 겠 습 니 다.규범 화 된 문서 의 설명 에 따라 대부분 requestAnimation Frame()과 requestIdleCallback()등 api 를 사용 하 는 것 을 추천 합 니 다.quueMicrotask 는 렌 더 링 을 막 기 때문에 좋 은 실천 이 아 닙 니 다.
async/await
async/await 는 전단 개발 자 에 게 있어 서 없어 서 는 안 될 것 입 니 다.여기 서도 우 리 는 실현 할 수 있 습 니 다.
(function() {
async function setAsyncTimeout(fn) {
Promise.resolve().then(fn);
}
let i = 0;
const start = Date.now();
async function test() {
if (i++ < 100) {
await setAsyncTimeout(test);
} else {
console.log('setAsyncTimeout :', Date.now() - start);
}
}
setAsyncTimeout(test);
})();
setTimeout 버 전과 비교 한 결과 다음 과 같 습 니 다.setAsyncTimeout 실행 시간:2
setTimeout 실행 시간:490
귀 찮 지 않 으 면 Promise 를 통 해 이 루어 질 수 있 습 니 다.사실은 모두 대동소이 합 니 다.코드 가 많 을 뿐만 아니 라 여 기 는 생략 합 니 다.
MessageChannel
Message Channel 은 새로운 메시지 채널 을 만 들 고 두 개의 Message Port 속성 을 통 해 데 이 터 를 보 낼 수 있 습 니 다.Message Channel 은 포트 개념 을 제공 하여 포트 간 의 통신 을 실현 합 니 다.예 를 들 어 worker/iframe 간 의 통신 등 입 니 다.
(function() {
const channel = new MessageChannel();
function setMessageChannelTimeout(fn) {
channel.port2.postMessage(null);
}
channel.port1.onmessage = function() {
test();
};
let i = 0;
const start = Date.now();
function test() {
if(i++ < 100) {
setMessageChannelTimeout(test);
} else {
console.log('setMessageChannelTimeout :', Date.now() - start);
}
}
setMessageChannelTimeout(test);
})();
setTimeout 버 전과 비교 한 결과 다음 과 같 습 니 다.setMessageChannel 타임 아웃 실행 시간:4
setTimeout 실행 시간:490
세 번 째 방식 은 앞의 두 가지 방식 보다 운행 시간 이 더 길다.Message Channel 을 통 해 발생 하 는 것 은 매크로 임무 이 고 다른 두 가 지 는 마이크로 임무 이 며 마이크로 임 무 는 앞 에 있 고 메 인 스 레 드 를 막 기 때문에 시간 이 좀 길다.
마지막.
본 고 는 세 가지 실현 방식 을 제 공 했 는데 모두 js 가 비동기 해결 방안 을 제공 하 는 것 을 중심 으로 이 루어 진 것 으로 실현 자체 가 복잡 하지 않다.
부록
【1】 https://mp.weixin.qq.com/s/QRIXBoKr2dMgLob3Atq9-g
【2】 https://dbaron.org/log/20100309-faster-timeouts
【3】 https://dbaron.org/mozilla/zero-timeout
js 가 0 ms 지연 타 이 머 를 실현 하 는 몇 가지 방식 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 js 지연 타 이 머 는 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[2022.04.19] 자바스크립트 this - 생성자 함수와 이벤트리스너에서의 this18일에 this에 대해 공부하면서 적었던 일반적인 함수나 객체에서의 this가 아닌 오늘은 이벤트리스너와 생성자 함수 안에서의 this를 살펴보기로 했다. new 키워드를 붙여 함수를 생성자로 사용할 때 this는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.