Reputation: 68064
I thought I was slowly getting to grips with Promises in Typescript/JS, but this has me baffled.
I'm trying to using Promises to wait for two JQuery getJSON requests to complete. With my browser - accessing a local server - everything works fine: But I've got a HAR log from a user showing the getJSON requests are duplicated, and the Promise resolves twice. I can't reproduce this behaviour at all, but it's consistent for the user, using Chrome 71 with plugins disabled.
I'd expect the console output to be like this...
Document Ready
File Loaded
Query Loaded
Got file and query
But instead - on this users machine, it's more like this
Document Ready
File Loaded
Query Loaded
File Loaded
Query Loaded
Got file and query
Got file and query
Here's slightly simplified code.
class Panel {
private pathName: string;
constructor(name: string) {
this.pathName = name;
}
async loadStuff(buster: string): Promise<any> {
// start to fetch the file JSON.
let fileP = $.getJSON(this.pathName + "/file.json", { mtime: buster });
// start to run the query
let queryP = $.getJSON("/api/query");
return fileP.then(async (data: any) => {
console.log("File loaded");
this.dosomething(data.objects);
return queryP.then((qdata: any) => {
console.log("Query loaded");
this.dosomethingelse(qdata);
});
}
, () => {
alert("Error loading '" + this.pathName + "/file.json'");
});
}
}
$(() => {
console.log("Document ready");
let bp: Panel = new Panel("foo");
let promise: Promise<void> = bp.loadStuff("test");
promise.then(() => {
console.log("Got file and query");
});
My best guess Is I'm doing something wrong with the Promises that's only triggered due to network timing conditions on the users machine. but I've no idea what!
Upvotes: 2
Views: 134
Reputation: 3098
This probably isn't a direct answer but it would be easier to reason about your code if you await your promises.
class Panel {
private pathName: string;
constructor(name: string) {
this.pathName = name;
}
async loadStuff(buster: string): Promise<any> {
try {
// start to fetch the file JSON.
let fileP = await $.getJSON(this.pathName + '/file.json', {
mtime: buster,
});
this.dosomething(fileP.objects);
// start to run the query
let queryP = await $.getJSON('/api/query');
this.dosomethingelse(queryP);
} catch (e) {
alert("Error loading '" + this.pathName + "/file.json'");
}
}
}
Upvotes: 1