fix: race condition in declaration-data.js

main
Henrik 2023-07-20 22:42:49 +02:00
parent 9af4c720f0
commit 5ce54e8e10
1 changed files with 25 additions and 17 deletions

View File

@ -25,6 +25,7 @@ export class DeclarationDataCenter {
* Used to implement the singleton, in case we need to fetch data mutiple times in the same page. * Used to implement the singleton, in case we need to fetch data mutiple times in the same page.
*/ */
static singleton = null; static singleton = null;
static requestSingleton = null;
/** /**
* Construct a DeclarationDataCenter with given data. * Construct a DeclarationDataCenter with given data.
@ -41,28 +42,35 @@ export class DeclarationDataCenter {
* @returns {Promise<DeclarationDataCenter>} * @returns {Promise<DeclarationDataCenter>}
*/ */
static async init() { static async init() {
if (!DeclarationDataCenter.singleton) { if (DeclarationDataCenter.singleton === null) {
const dataListUrl = new URL( if (DeclarationDataCenter.requestSingleton === null) {
`${SITE_ROOT}/declarations/declaration-data.bmp`, DeclarationDataCenter.requestSingleton = DeclarationDataCenter.getData();
window.location
);
// try to use cache first
const data = await fetchCachedDeclarationData().catch(_e => null);
if (data) {
// if data is defined, use the cached one.
DeclarationDataCenter.singleton = new DeclarationDataCenter(data);
} else {
// undefined. then fetch the data from the server.
const dataListRes = await fetch(dataListUrl);
const data = await dataListRes.json();
await cacheDeclarationData(data);
DeclarationDataCenter.singleton = new DeclarationDataCenter(data);
} }
await DeclarationDataCenter.requestSingleton;
} }
return DeclarationDataCenter.singleton; return DeclarationDataCenter.singleton;
} }
static async getData() {
const dataListUrl = new URL(
`${SITE_ROOT}/declarations/declaration-data.bmp`,
window.location
);
// try to use cache first
const data = await fetchCachedDeclarationData().catch(_e => null);
if (data) {
// if data is defined, use the cached one.
DeclarationDataCenter.singleton = new DeclarationDataCenter(data);
} else {
// undefined. then fetch the data from the server.
const dataListRes = await fetch(dataListUrl);
const data = await dataListRes.json();
await cacheDeclarationData(data);
DeclarationDataCenter.singleton = new DeclarationDataCenter(data);
}
}
/** /**
* Search for a declaration. * Search for a declaration.
* @returns {Array<any>} * @returns {Array<any>}