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:
JoostK 2018-11-18 22:04:43 +01:00 committed by Igor Minar
parent 46bc910ecb
commit b5ed403bc4
1 changed files with 7 additions and 4 deletions

View File

@ -15,13 +15,15 @@ import {ResourceLoader} from './annotations';
*/
export class HostResourceLoader implements ResourceLoader {
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>) {}
preload(url: string): Promise<void>|undefined {
if (this.cache.has(url) || this.fetching.has(url)) {
if (this.cache.has(url)) {
return undefined;
} else if (this.fetching.has(url)) {
return this.fetching.get(url);
}
const result = this.host(url);
@ -29,11 +31,12 @@ export class HostResourceLoader implements ResourceLoader {
this.cache.set(url, result);
return undefined;
} else {
this.fetching.add(url);
return result.then(str => {
const fetchCompletion = result.then(str => {
this.fetching.delete(url);
this.cache.set(url, str);
});
this.fetching.set(url, fetchCompletion);
return fetchCompletion;
}
}