繁体   English   中英

Web Workers中的微任务

[英]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都会发生这种情况。

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

  1. 不要使用promise,回到回调地狱
  2. 同步使用诺言

这两个选项都非常不令人满意。 所以我问您,Stack Overflow,您知道在Web Worker中排队微任务的方法吗?

简短的答案:您无法在网络工作者中做到这一点

长答案:没有实际的微任务api,只有黑客可以尝试模拟它们。 不幸的是,效果最好的变量(变异观察者)主要与DOM有关,因此它们仅在主线程中可用,而在Web worker中不可用。 话虽这么说,对于IDB并保证标准化官方关系可能是有意义的,但我不确定是否确实有人提出承诺,因为IDB的承诺和IDB来自不同的群体。 实际上,浏览器供应商可能会对在Web worker中执行真正的微任务api产生吸引力,因为大多数反对意见都与意外地占用主线程有关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM