#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
});
Отказ от ответственности: я не тестировал этот код, и он просто закодирован. Пожалуйста, ответьте, является ли это рабочим решением, если вы попробуете это или если есть какие-либо опечатки во фрагментах кода.