fix(ivy): prevent ngtsc from synchronous compilation for in-flight resouces (#27357)
When a single resource is preloaded twice in ngtsc, the second request would be recognized as in-flight in which case `undefined` would be returned, which signals to the compilation that is can resume synchronously. The compilation would then proceed immediately and call `load`, only to find out that the request is still in-flight which is not allowed. This commit caches the Promise of the in-flight fetch requests, such that subsequent preload requests can return the corresponding Promise instance. PR Close #27357
This commit is contained in:
parent
46bc910ecb
commit
b5ed403bc4
|
@ -15,13 +15,15 @@ import {ResourceLoader} from './annotations';
|
||||||
*/
|
*/
|
||||||
export class HostResourceLoader implements ResourceLoader {
|
export class HostResourceLoader implements ResourceLoader {
|
||||||
private cache = new Map<string, string>();
|
private cache = new Map<string, string>();
|
||||||
private fetching = new Set<string>();
|
private fetching = new Map<string, Promise<void>>();
|
||||||
|
|
||||||
constructor(private host: (url: string) => string | Promise<string>) {}
|
constructor(private host: (url: string) => string | Promise<string>) {}
|
||||||
|
|
||||||
preload(url: string): Promise<void>|undefined {
|
preload(url: string): Promise<void>|undefined {
|
||||||
if (this.cache.has(url) || this.fetching.has(url)) {
|
if (this.cache.has(url)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
} else if (this.fetching.has(url)) {
|
||||||
|
return this.fetching.get(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this.host(url);
|
const result = this.host(url);
|
||||||
|
@ -29,11 +31,12 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
this.cache.set(url, result);
|
this.cache.set(url, result);
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
this.fetching.add(url);
|
const fetchCompletion = result.then(str => {
|
||||||
return result.then(str => {
|
|
||||||
this.fetching.delete(url);
|
this.fetching.delete(url);
|
||||||
this.cache.set(url, str);
|
this.cache.set(url, str);
|
||||||
});
|
});
|
||||||
|
this.fetching.set(url, fetchCompletion);
|
||||||
|
return fetchCompletion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue