简体   繁体   English

中止 Dexie.js 查询

[英]Aborting Dexie.js query

In my application, the user specifies some part of the query.在我的应用程序中,用户指定查询的某些部分。 I react immediately after the user changes something in the query.在用户更改查询中的某些内容后,我会立即做出反应。 On large data sets, this is a problem - the query can take about 2 seconds to complete and sometimes the users apply additional constraints before the query completes, thus a new query is created and consequently the users overwhelm the system by applying too many queries simultaneously.在大型数据集上,这是一个问题 - 查询可能需要大约 2 秒才能完成,有时用户会在查询完成之前应用额外的约束,因此会创建一个新查询,因此用户会因同时应用太多查询而使系统不堪重负. When multiple queries run, even the 2-second query becomes 30 seconds query.当多个查询运行时,即使是 2 秒的查询也会变成 30 秒的查询。 This is a pathological corner-case and it is not desirable for the users to have an extra button to fire the query once they specify all parameters.这是一个病态的极端情况,用户在指定所有参数后不希望有一个额外的按钮来触发查询。

Is there a possibility in Dexie to cancel the query before it is finished? Dexie 是否有可能在查询完成之前取消查询? I would like to cancel the previous query when the user specifies a new one.当用户指定新查询时,我想取消上一个查询。

Transactions can be aborted.事务可以中止。 I haven't tested, but one way should be if you open every query in a transaction and store the transaction in a state so you cane abort the previous transaction when a new one is about to fire.我还没有测试过,但一种方法应该是,如果您打开事务中的每个查询并将事务存储在一种状态,以便在新事务即将触发时中止前一个事务。

function cancellableDexieQuery(includedTables, querierFunction) {
  let tx = null;
  let cancelled = false;
  const promise = db.transaction('r', includedTables, () => {
    if (cancelled) throw new Dexie.AbortError('Query was cancelled');
    tx = Dexie.currentTransaction;
    return querierFunction();
  });
  return [
    promise,
    () => {
      cancelled = true; // In case transaction hasn't been started yet.
      if (tx) tx.abort(); // If started, abort it.
      tx = null; // Avoid calling abort twice.
    }
  ];
}

Then as an example of using this helper function:然后作为使用此辅助函数的示例:

const [promise1, cancel1] = cancellableDexieQuery(
  "friends",
  ()=>db.friends.where('name').startsWith('A').toArray()
);

cancel1(); // Cancel the operation we just started.

const [promise2, cancel2] = cancellableDexieQuery(
  "friends",
  ()=>db.friends.where('name').startsWith('B').toArray()
);

promise1.catch(error => {
  // Expect a Dexie.AbortError
}

promise2.then(result => {
  // Expect the array as result
});

Disclaimber: I haven't tested this code and it's just dry-coded.免责声明:我还没有测试过这段代码,它只是干编码的。 Please reply about whether it is a working solution if you try this out or if there are any typos in the code snippets.如果您尝试这样做或者代码片段中是否有任何拼写错误,请回复它是否是一个有效的解决方案。

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

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