网络工人内部的微型箱



任务和微型掩码之间的区别很重要,因为索引dexeddb交易跨任务,而不是微型施法。在Promises中包装索引DB代码时,这是有问题的,因为在Firefox(也许还有其他浏览器)中,Promise解决方案不会在Microtask中发生,因此您的交易将提交。

解决此问题的解决方案是使用使用MicroTasks的第三方承诺实现。lie是其中一个库之一,在引擎盖下,它将微型箱问题抽象到另一个名为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 Worker中运行它时,它会失败,因为在回调之前,在调用immediate时进行的交易会进行。这发生在铬和firefox中。

截至目前,我已经想到了两种解决方案:

  1. 不要使用承诺,回到回调地狱
  2. 使用同步分辨率的承诺

这两种选项都高度毫无影利。所以我问你,堆叠溢出,您知道一种在网络工作人员内排队微型掩体的方法吗?

简短答案:您不能在Web Worker中做到这一点

长答案:没有实际的Microtask API,只有黑客可以尝试模拟它们。不幸的是,那些最有效的(突变观察者)主要与DOM有关,因此它们仅在主线程中可用。话虽如此,对于IDB来说,这可能是有意义的,并承诺将正式关系标准化,我不确定是否真的指出了一个人,因为承诺和IDB来自不同的群体。实际上,浏览器供应商可能会在Web工作人员内部进行真实的微型API,因为大多数反对意外的反对与意外构成主线程有关。

最新更新