Roddy
Roddy

Reputation: 68064

Typescript Promise with JQuery seems to run twice?

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

Answers (1)

denixtry
denixtry

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

Related Questions