javascript - 如果浏览器不支持本机 Promises,如何将微任务排队?
问题描述
最好编写不依赖于立即回调时间的代码(例如微任务与宏任务),但我们暂时将其放在一边。
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');
a在已解决的 Promise 上的行为与立即回调.then
的行为根本不同- Promise将首先运行,即使它首先排队。但只有现代浏览器支持 Promises。如果不存在微任务的特殊功能,如何正确填充?setTimeout
.then
setTimeout
Promise
如果您尝试使用 模仿.then
的微任务,您将排队的是宏任务,而不是微任务,因此如果宏任务已经排队setTimeout
,那么糟糕的 polyfill将不会在正确的时间运行。.then
有一个使用 的解决方案MutationObserver
,但它看起来很难看,不是什么MutationObserver
用途。此外,MutationObserver
IE10 及更早版本不支持。如果一个人想在一个本身不支持 Promises 的环境中排队一个微任务,有没有更好的选择?
(我实际上并没有尝试支持 IE10 - 这只是关于如何在没有 Promise 的情况下对微任务进行排队的理论练习)
解决方案
我看到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 并查看上面的工作,但代码看起来很奇怪。
推荐阅读
- javascript - 如何从 this.state POST 数据?
- gcc - OpenMP/OpenACC 实现和 gcc/PGI 编译器之间的结果差异
- amazon-web-services - AWS Elastic Beanstalk - 添加了 SSL 证书但仍然是 HTTPS 错误:SSL_ERROR_BAD_CERT_DOMAIN
- spring - Docker compose 中的 Eureka 客户端注册失败:无法注册为客户端 - 但 eureka 服务器和客户端已单独启动并运行
- java - RSocket Java(服务器)/ C#(客户端):无法解码为 [ch.Person]GenericMessage
- go - 为什么 go list -m 命令列出我项目中一些未使用的模块?
- nginx - Strapi 中的有效载荷太大
- c# - Caliburn.Micro Task.run() 阻塞 UI 线程
- nginx - Nginx 443 端口已经被它自己使用了?
- reactjs - 通过 React js 使用三元运算符进行具有 >2 条件的内联样式