Прерывание Dexie.js запрос

#javascript #dexie #dexiejs

#javascript #dexie

Вопрос:

В моем приложении пользователь указывает некоторую часть запроса. Я реагирую сразу после того, как пользователь что-то меняет в запросе. Для больших наборов данных это проблема — выполнение запроса может занять около 2 секунд, и иногда пользователи применяют дополнительные ограничения до завершения запроса, таким образом создается новый запрос, и, следовательно, пользователи перегружают систему, применяя слишком много запросов одновременно. При выполнении нескольких запросов даже 2-секундный запрос становится 30-секундным запросом. Это патологический случай, и пользователям нежелательно иметь дополнительную кнопку для запуска запроса после указания всех параметров.

Есть ли в Dexie возможность отменить запрос до его завершения? Я хотел бы отменить предыдущий запрос, когда пользователь укажет новый.

Ответ №1:

Транзакции могут быть прерваны. Я не тестировал, но один из способов должен быть, если вы открываете каждый запрос в транзакции и сохраняете транзакцию в состоянии, чтобы вы могли прервать предыдущую транзакцию, когда новая собирается сработать.

 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.
    }
  ];
}
  

Затем в качестве примера использования этой вспомогательной функции:

 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
});
  

Отказ от ответственности: я не тестировал этот код, и он просто закодирован. Пожалуйста, ответьте, является ли это рабочим решением, если вы попробуете это или если есть какие-либо опечатки во фрагментах кода.