즉각적인 콜백 타이밍에 의존하지 않는 코드를 작성하는 것이 좋습니다 (마이크로 태스크와 매크로 태스크와 같은).
setTimeout
매크로 작업을 대기열에 넣습니다.이 작업은 최소한 모든 마이크로 태스크 (및 생성 된 마이크로 태스크)가 완료 될 때까지 대기합니다. 예를 들면 다음과 같습니다.
console.log('Macrotask queued');
setTimeout(function() {
console.log('Macrotask running');
});
Promise.resolve()
.then(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');
.then
해결 된 약속에 대한 동작 은 기본 setTimeout
콜백 동작과 근본적으로 다릅니다 . 약속 .then
이 먼저 setTimeout
대기 하더라도 약속 이 먼저 실행됩니다 . 그러나 최신 브라우저 만 약속을 지원합니다. 존재하지 않는 경우 마이크로 태스크 의 특수 기능을 어떻게 제대로 채울 수 Promise
있습니까?
.then
를 사용하여의 마이크로 태스크 를 모방하려고 setTimeout
하면 마이크로 태스크가 아닌 매크로 태스크를 큐에 넣게되므로 .then
매크로 태스크가 이미 대기중인 경우 잘못 채워진 것이 적시에 실행되지 않습니다.
를 사용하는 솔루션이 MutationObserver
있지만 추악한 것처럼 보이며 목적이 아닙니다 MutationObserver
. 또한 MutationObserver
IE10 및 이전 버전에서는 지원되지 않습니다. 약속을 기본적으로 지원하지 않는 환경에서 마이크로 태스크를 대기시키려는 경우 더 나은 대안이 있습니까?
( 실제로 IE10을 지원하려고 하지는 않습니다. 이것은 약속없이 마이크로 태스킹을 대기하는 방법에 대한 이론적 인 연습 일뿐입니다)
답변
우리가 IE에 대해 이야기하고 있다면 setImmediate
https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
또한 MutationObserver는 IE10 및 이전 버전에서 지원되지 않습니다.
setImmediate
IE10에서 지원됩니다. IE 버전 하나 더하기.
그리고 관심이 있다면 Node.js를 추가하십시오.
MutationObserver를 사용하는 솔루션이 있지만보기 흉하게 보이며 MutationObserver가 아닙니다.
다른 가능한 polyfills 여기 구현의 몇 가지가있다 :
https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (이 하나가 MDN에서 언급)
https://github.com/taylorhakes/ setAsap / blob / master / setAsap.js (더 간단한 것)
그리고 거의 모든 폴리 필로도 추악합니다.
그러나 어쨌든 여기에 본질의 예가 있습니다 (postMessage 사용). 그리고 그것이 가장 추악하다고 생각합니다 (그러나 진정한 polyfill은 아닙니다)
var setImmediate = (function() {
var queue = [];
function on_message(e) {
if(e.data === "setImmediateMsg") queue.pop()()
}
if(window.addEventListener) { // IE9+
window.addEventListener('message', on_message)
} else { // IE8
window.attachEvent('onmessage', on_message)
}
return function(fn) {
queue.unshift(fn)
window.postMessage("setImmediateMsg", "*")
}
}())
setTimeout(function() {
console.log('Macrotask running');
});
console.log('Macrotask queued');
setImmediate(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');
답변
mutationObserver
콜백이 마이크로 태스킹을 사용 하는 것을 보았고 다행히도 IE11이 지원하므로 콜백을 저장 한 다음 요소를 변경하여 관찰자를 즉시 트리거하여 IE11에서 마이크로 태스킹을 대기시키는 아이디어를 얻었습니다.
var weirdQueueMicrotask = (function() {
var elementThatChanges = document.createElement('div');
var callback;
var bool = false;
new MutationObserver(function() {
callback();
}).observe(elementThatChanges, { childList: true });
return function(callbackParam) {
callback = callbackParam;
elementThatChanges.textContent = bool = !bool;
};
})();
setTimeout(function() {
console.log('Macrotask running');
});
console.log('Macrotask queued');
weirdQueueMicrotask(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');
IE11을 열고 위의 작동을 볼 수 있지만 코드가 이상하게 보입니다.