From b5ed403bc40cab8397468b721028cc44a833973c Mon Sep 17 00:00:00 2001 From: JoostK Date: Sun, 18 Nov 2018 22:04:43 +0100 Subject: [PATCH] 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 --- packages/compiler-cli/src/ngtsc/resource_loader.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/resource_loader.ts b/packages/compiler-cli/src/ngtsc/resource_loader.ts index ea54032e3c..3ab9118f7a 100644 --- a/packages/compiler-cli/src/ngtsc/resource_loader.ts +++ b/packages/compiler-cli/src/ngtsc/resource_loader.ts @@ -15,13 +15,15 @@ import {ResourceLoader} from './annotations'; */ export class HostResourceLoader implements ResourceLoader { private cache = new Map(); - private fetching = new Set(); + private fetching = new Map>(); constructor(private host: (url: string) => string | Promise) {} preload(url: string): Promise|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; } }