dum*_*ter 10 javascript web-worker promise indexeddb
任务和微任务之间的区别很重要,因为IndexedDB事务跨任务提交,而不是微任务.在Promises中包装IndexedDB代码时会出现问题,因为在Firefox(可能还有其他浏览器)中,微任务中不会发生承诺解析,因此您的事务将提交.
此问题的解决方案是使用使用微任务的第三方承诺实现.lie它是其中一个库,并且它将微任务问题抽象到另一个名为的库中immediate,该库MutationObserver用于生成微任务.
大部分时间都很好用.但是在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);
});
};
Run Code Online (Sandbox Code Playgroud)
当我正常运行时,它工作正常.当我在Web Worker中运行它时,它会失败,因为immediate在回调运行之前,事务在调用时提交.这在Chrome和Firefox中都会发生.
截至目前,我已经想到了两个解决方案:
这两个选项都非常不稳定.所以我问你,Stack Overflow,你知道一种在Web Worker中排队微任务的方法吗?
简短的回答:你不能在网络工作者那里做到这一点
答案很长:没有实际的微任务api,只有黑客才能尝试模拟它们.不幸的是,那些效果最好的(变异观察者)主要与DOM有关,因此它们仅在主要线程中可用,而不在Web工作者中.据说这可能对IDB有意义,并承诺将官方关系标准化,我不确定是否确实有一个作为承诺而且IDB来自不同的团体.浏览器供应商实际上可能会有一些关于在Web工作者中进行真正的微任务API的牵引力,因为大多数异议都与意外泄漏主线程有关.