Skip to content

Commit

Permalink
Resolve #1831
Browse files Browse the repository at this point in the history
  • Loading branch information
dfahlander committed Nov 27, 2023
1 parent 5401805 commit 19ea760
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/live-query/live-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
decrementExpectedAwaits,
endMicroTickScope,
incrementExpectedAwaits,
NativePromise,
newScope,
PSD,
usePSD,
Expand Down Expand Up @@ -43,11 +44,22 @@ export function liveQuery<T>(querier: () => T | Promise<T>): IObservable<T> {
if (scopeFuncIsAsync) {
incrementExpectedAwaits();
}
const rv = newScope(querier, ctx);
let rv = newScope(querier, ctx);
if (scopeFuncIsAsync) {
(rv as Promise<any>).finally(decrementExpectedAwaits);
// Make sure to set rv = rv.finally in order to wait to after decrementExpectedAwaits() has been called.
// This fixes zone leaking issue that the liveQuery zone can leak to observer's next microtask.
rv = (rv as Promise<any>).finally(decrementExpectedAwaits);
}
return rv;
return Promise.resolve(rv).finally(()=>{
if (PSD.subscr === ctx.subscr) {
// Querier did not await all code paths. We must wait for the next macrotask to run in order to
// escape from zone echoing. Warn to console so that app code can be corrected. liveQuery callbacks
// shall be pure functions and should never spawn side effects - so there is never a need to call
// other async functions or generated promises without awaiting them.
console.warn(`Dexie liveQuery()'s querier callback did'nt await all of its spawned promises. Querier source: ${querier}`);
return new NativePromise(resolve => setTimeout(resolve, 0)); // Wait for the next macrotask to run.
}
});
} finally {
wasRootExec && endMicroTickScope(); // Given that we created the microtick scope, we must also end it.
}
Expand Down Expand Up @@ -130,7 +142,7 @@ export function liveQuery<T>(querier: () => T | Promise<T>): IObservable<T> {
if (!objectIsEmpty(currentObs) && !startedListening) {
globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
startedListening = true;
}
}
observer.next && observer.next(result);
},
(err) => {
Expand Down

0 comments on commit 19ea760

Please sign in to comment.