向indexedDB添加许多项

时间:2017-11-21 12:18:42

标签: indexeddb

在寻找向indexedDB添加许多项目时,我正在寻找最佳实践。项目数量的上限通常约为100k,每个项目都是一个js对象,通常约为350字节。

我维护了一个待处理项目(操作)列表,这些项目要在数据库上进行(每个操作都是"添加"," put"或者"删除&#34 ;),每个项目可以属于不同的对象存储区。

我只需要取第一个项目,将其应用到相应的objectStore,一旦完成(成功或不成功),我将继续下一个项目。

有更好(更有效)的方法吗?是否有任何范围问题w.r.t.交易生命周期我需要关注下面的片段吗?

function flushPendingDbActions() {
    var transaction = db.transaction(storeNames, "readwrite");

    var addNext = function() {
        var nextItem = pendingDbActions[0];
        if (nextItem) {
            pendingDbActions.shift();

            var objectStore = transaction.objectStore(nextItem.store),
                params,
                request;

            switch(nextItem.action) {
            case 'add':
            case 'put':
                params = nextItem;
                break;
            case 'delete':
                params = nextItem.key;
                break;
            }

            request = objectStore[nextItem.action](params);
            request.onsuccess = request.onerror = addNext;
        }
    };

    addNext();
}

1 个答案:

答案 0 :(得分:1)

对我来说没问题,但有几件事情:

  • 我会在错误时停止前进迭代。错误事件有时表明某些事情确实是错误的,并且该事务的所有后续请求都可能也会失败,并且通过继续错误路径,您将导致N个更多错误,其中N是剩余数字。
  • 我使用堆栈或lifo访问模式。将项目附加到阵列上,然后将其弹出以进行前进。避免使用shift和fifo-queue之类的访问,这只是js中的错误,因为shift比pop更多的工作。这当然是挑剔,但你有点问及效率。只有处理大量的N才有意义。
  • 根据项目数量的不同,您可能会遇到堆栈溢出类型的错误,因为每个请求都是所谓堆栈上的挂起函数,从您的代码看起来它就像无限堆积一样。在这种情况下,您可能希望将请求批处理为100或1000或其他类似的块,以避免出现该问题,但这仅在您甚至超过阈值数量以及运行代码的特定平台时才重要(例如在手机上可能遇到麻烦)。
  • 然后有一个更微妙的异步问题。现在,您在发出下一个请求之前等待每个请求完成。为什么?如果请求在逻辑上是独立的,则立即将它们全部关闭,并等待事务完成(在最后一个挂起的请求完成时完成)。您通常只需要使用您现在使用的模式,如果每个后续请求的逻辑都根据先前的请求进行更改,则每个操作都会等待所有先前的操作结算。因此,如果请求是独立的,那么您将在不需要任何操作的情况下引入空闲,并且基本上无限制地限制自己的速度。

修改 - 添加内容:

根据https://www.w3.org/TR/IndexedDB-2/#transaction-lifetime-concept

  

除非另有规定,否则请求必须按照对交易的顺序执行。同样,他们的结果必须按照针对特定交易的请求的顺序返回。

因此,您应该能够同时启动请求而不是串行启动请求,这应该避免TransactionInactiveError。即使您发出相当于add item > delete item的请求,也是如此。

然后由于请求位于堆栈中而遇到堆栈溢出问题,因为请求位于堆栈中,然后在这种情况下应考虑缓冲。因此,请使用pendingactions数组并以块的形式处理它。让我们说1000一次,将1000传递给一个processchunk帮助函数,它会触发1000个并发请求,等待它完成,然后处理下一个块,直到所有块都被处理完毕。