Skip to content

Commit 01597da

Browse files
authored
Allow use of zone wrappers outside inejection context (#3589)
1 parent 6b1b0ca commit 01597da

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/zones.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
22
import {
33
Injectable,
4+
Injector,
45
NgZone,
56
PendingTasks,
67
inject
@@ -97,7 +98,7 @@ const zoneWrapFn = (
9798
) => {
9899
return (...args: any[]) => {
99100
if (taskDone) {
100-
setTimeout(taskDone, 10);
101+
setTimeout(taskDone, 0);
101102
}
102103
return run(() => it.apply(this, args));
103104
};
@@ -108,12 +109,22 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
108109
return function () {
109110
let taskDone: VoidFunction | undefined;
110111
const _arguments = arguments;
112+
let schedulers: ɵAngularFireSchedulers;
113+
let pendingTasks: PendingTasks;
114+
let injector: Injector;
115+
try {
116+
schedulers = getSchedulers();
117+
pendingTasks = inject(PendingTasks);
118+
injector = inject(Injector);
119+
} catch(e) {
120+
return (it as any).apply(this, _arguments);
121+
}
111122
// if this is a callback function, e.g, onSnapshot, we should create a pending task and complete it
112123
// only once one of the callback functions is tripped.
113124
for (let i = 0; i < arguments.length; i++) {
114125
if (typeof _arguments[i] === 'function') {
115126
if (blockUntilFirst) {
116-
taskDone ||= run(() => inject(PendingTasks).add());
127+
taskDone ||= run(() => pendingTasks.add());
117128
}
118129
// TODO create a microtask to track callback functions
119130
_arguments[i] = zoneWrapFn(_arguments[i], taskDone);
@@ -122,7 +133,6 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
122133
const ret = runOutsideAngular(() => (it as any).apply(this, _arguments));
123134
if (!blockUntilFirst) {
124135
if (ret instanceof Observable) {
125-
const schedulers = getSchedulers();
126136
return ret.pipe(
127137
subscribeOn(schedulers.outsideAngular),
128138
observeOn(schedulers.insideAngular),
@@ -132,18 +142,17 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
132142
}
133143
}
134144
if (ret instanceof Observable) {
135-
const schedulers = getSchedulers();
136145
return ret.pipe(
137146
subscribeOn(schedulers.outsideAngular),
138147
observeOn(schedulers.insideAngular),
139-
pendingUntilEvent(),
148+
pendingUntilEvent(injector),
140149
);
141150
} else if (ret instanceof Promise) {
142151
// eslint-disable-next-line @typescript-eslint/no-misused-promises
143152
return run(
144153
() =>
145154
new Promise((resolve, reject) => {
146-
inject(PendingTasks).run(() => ret).then(
155+
pendingTasks.run(() => ret).then(
147156
(it) => run(() => resolve(it)),
148157
(reason) => run(() => reject(reason))
149158
);
@@ -153,7 +162,7 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
153162
// Handle unsubscribe
154163
// function() is needed for the arguments object
155164
return function () {
156-
setTimeout(taskDone, 10);
165+
setTimeout(taskDone, 0);
157166
return ret.apply(this, arguments);
158167
};
159168
} else {

0 commit comments

Comments
 (0)