首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果浏览器不支持本机承诺,如何对微任务进行排队?

如果浏览器不支持本机承诺,如何对微任务进行排队?
EN

Stack Overflow用户
提问于 2019-12-18 11:50:48
回答 2查看 737关注 0票数 11

最好是编写不依赖于立即回调的时间的代码(比如微任务和宏任务),但让我们暂时搁置一下。

setTimeout排队一个宏任务,该宏任务至少等待启动,直到所有的微任务(以及它们生成的微任务)完成。下面是一个例子:

代码语言:javascript
复制
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回调的行为有根本的不同--即使setTimeout是先排队的,承诺.then也会首先运行。但只有现代浏览器支持承诺。如果Promise不存在,如何正确填充微任务的特殊功能?

如果您试图使用.then的微任务来模拟setTimeout,您将排队的是一个宏任务,而不是一个微任务,因此如果一个宏任务已经排队,那么严重多填充的.then将无法在正确的时间运行。

有一个使用MutationObserver的解决方案,但它看起来很难看,而且不是MutationObserver的用途。而且,MutationObserver在IE10和更早版本中不受支持。如果一个人想在一个本机不支持承诺的环境中排队,有没有更好的选择?

(我实际上并没有试图支持IE10 -这只是一个关于微任务如何在没有承诺的情况下排队的理论练习)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-10 12:14:02

如果我们谈论的是IE,你可以使用setImmediate

https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate

此外,

和更早版本的IE10不支持MutationObserver。

setImmediate在IE10上得到支持。再加上一个IE版本。

如果你有兴趣的话,再加上Node.js。

有一个使用MutationObserver的解决方案,但是它看起来很难看,而不是MutationObserver的用途。

还有其他可能的多填充,下面是几个实现:https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (这个在MDN中提到) https://github.com/taylorhakes/setAsap/blob/master/setAsap.js (一个更简单的)

而且几乎所有的填充物都是丑陋的。

但是无论如何,这里有一个例子,它的本质(使用postMessage),我认为它是最不丑陋的(但也不是一个真正的填充)

代码语言:javascript
复制
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');

票数 4
EN

Stack Overflow用户

发布于 2019-12-18 11:50:48

我看到mutationObserver回调使用了微任务,幸运的是,IE11支持它,所以我想在IE11中排队,方法是保存回调,然后通过更改元素立即触发观察者:

代码语言:javascript
复制
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并看到上面的工作,但是代码看起来很奇怪。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59391420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档