[英]Microtasks inside Web Workers
任务和微任务之间的区别很重要,因为IndexedDB事务跨任务提交,但跨微任务提交 。 在Promises中包装IndexedDB代码时,这是有问题的,因为在Firefox(以及其他浏览器)中,promise解析不会在微任务中发生,因此您的事务将提交。
解决此问题的方法是使用使用微任务的第三方promise实现。 lie
是这些库中的一个,和引擎盖下它抽象的microtask问题成称为另一个库immediate
,它使用MutationObserver
生成microtasks。
在大多数情况下,效果都很好。 但是在Web Worker中, MutationObserver
不存在,因此该技巧不起作用。 这是一个易于运行的GitHub存储库中的问题示例。 基本上我有以下代码:
var immediate = require('immediate');
var openRequest = indexedDB.open('firefox-indexeddb-promise-worker-test');
openRequest.onupgradeneeded = function() {
var db = openRequest.result;
var store = db.createObjectStore('whatever', {keyPath: 'id'});
store.put({id: 1});
store.put({id: 2});
store.put({id: 3});
};
function get(tx, id, cb) {
immediate(function () {
var req = tx.objectStore('whatever').get(id);
req.onsuccess = function (e) {
console.log('got', e.target.result);
if (cb) {
cb(null, e.target.result);
}
};
req.onerror = function (e) {
console.error(e.target.error);
if (cb) {
cb(e.target.error);
}
};
});
}
openRequest.onsuccess = function() {
var db = openRequest.result;
var tx = db.transaction('whatever');
tx.oncomplete = function () {
console.log('tx complete');
};
get(tx, 1, function () {
get(tx, 2);
});
};
当我正常运行时,它可以正常工作。 当我在Web工作运行它,因为它的事务提交失败时immediate
被调用时,回调运行之前。 Chrome和Firefox都会发生这种情况。
到目前为止,我已经想到了两种解决方案:
这两个选项都非常不令人满意。 所以我问您,Stack Overflow,您知道在Web Worker中排队微任务的方法吗?
简短的答案:您无法在网络工作者中做到这一点
长答案:没有实际的微任务api,只有黑客可以尝试模拟它们。 不幸的是,效果最好的变量(变异观察者)主要与DOM有关,因此它们仅在主线程中可用,而在Web worker中不可用。 话虽这么说,对于IDB并保证标准化官方关系可能是有意义的,但我不确定是否确实有人提出承诺,因为IDB的承诺和IDB来自不同的群体。 实际上,浏览器供应商可能会对在Web worker中执行真正的微任务api产生吸引力,因为大多数反对意见都与意外地占用主线程有关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.