비동기적으로 함수를 실행하고 싶다면 가장 먼저 생각하는 방법은 바로 setTimeout입니다<br> 예: setTimeout(function( /* 1초 후에 작업 수행 */){},1000}
최대한 빨리 비동기적으로 함수를 실행하고 싶다면 어떻게 해야 할까요? <br> 그럴까요:
setTimeout(function( /* 尽快做点什么 */){},0}
안타깝게도 setTimeout 중첩으로 인해 UI 스레드가 차단될 가능성을 피하기 위해 브라우저에서는 setTimeout에 대한 최소 실행 시간 간격을 설정합니다. 브라우저마다 최소 실행 시간 간격이 다릅니다. 크롬에서 테스트했을 때 setTimeout 0의 실제 실행 시간 간격은 약 12ms입니다. <br> <br> 그렇다면 가능한 한 빨리 함수를 비동기적으로 실행하고 싶다면 속도를 높일 수 있는 방법이 있을까요?
먼저 브라우저 측면에서 일반적으로 사용되는 비동기 실행 방법이 무엇인지 살펴보겠습니다
setImmediate: 이 메소드는 setTimeout 0보다 빠른 비동기 실행을 달성하고 실행 시간은 0ms에 가깝지만 IE/노드에서만 지원됩니다.
requestAnimationFrame: 이 메서드는 애니메이션 루프를 수행할 때 자주 사용됩니다. 이 메서드는 브라우저가 UI를 새로 고칠 때에만 실행됩니다. UI 새로 고침의 최대 빈도는 일반적으로 60fps이므로 requestAnimationFrame은 일반적으로 setTimeout 0보다 느립니다.
비동기 함수를 사용하는 것 외에도 비동기 호출을 구현하는 몇 가지 방법이 있습니다
메시지 사용: <br> onmessage 메소드는 iframe과 통신할 때 자주 사용되지만, 동일한 창이 자체적으로 메시지를 게시하면 어떻게 될까요? 실제로 이는 함수를 비동기적으로 실행하는 것과 같습니다<br> 예:
var doSth = function(){} window.addEventListener("message", doSth, true); window.postMessage("", "*");
<br>
또한 스크립트 태그를 사용하여 함수의 비동기 실행을 구현할 수도 있습니다. 예를 들면 다음과 같습니다. <br>
<br>
var newScript = document.createElement("script"); newScript.onreadystatechange = doSth; document.documentElement.appendChild(newScript);
<br>
<br>
문서에 스크립트를 추가하면 onreadystatechange도 실행되지만 이 방법은 IE 브라우저에서만 사용할 수 있습니다.
그러면 이 중 어떤 방법이 가장 빠른가요?
테스트해봤습니다.
크롬 아래:
setImmediate: 사용할 수 없습니다. <br> setTimeout 0:12ms<br> 메시지 수신 시간: 6ms<br> onreadystatechange: 지원되지 않음
Chrome에서는 onmessage가 setTimeout 0보다 빠릅니다.
파이어폭스에서:
setImmediate: 사용할 수 없습니다. <br> setTimeout 0:7ms<br> 메시지 수신 시간: 7ms<br> onreadystatechange: 지원되지 않음
Firefox에서는 onmessage와 setTimeout 0이 똑같이 빠릅니다.
IE9:
setImmediate: 사용할 수 없습니다. <br> 설정시간 초과 0:11ms<br> 온메시지: 7ms 10ms<br> onreadystatechange: 2ms
IE9에서는 onreadystatechange 시간이 다른 두 가지보다 훨씬 빠릅니다.
일반적으로 setImmediate < Readystatechange < onmessage < setTimeout 0 < requestAnimationFrame<br> 따라서 비동기 함수를 빠르게 실행하는 메서드를 간단하게 캡슐화할 수 있습니다.
var setZeroTimeout = (function(){ if(window.setImmediate){ //IE10+版本,使用原生setImmediate return window.setImmediate; } else if("onreadystatechange" in document.createElement("script")){ return function(){/* 使用onreadystatechange的版本 */} } else if(window.postMessage){ return function(){/* 使用onmessage的异步执行版本 */} } else { return window.setTimeout; } })();