Noam
Noam

Reputation: 5276

Sequential Promises in typescript

I have a typescript class with a save method, and I want the next call to the save method, to only happen once the first one is completed. Imagine the following case:

  count = 0;
  async save() {
      let x = this.count++;
      console.log("start " + x);
      await axios.post("***",{});
      console.log("end " + x);
  }
}

In this case - when the user calls save, without awaiting it - the second post can be called before the first one completed - causing all sorts of problems.

The solution that I came up with is:

  lastSave = Promise.resolve();
  count = 0;
  async save() {
    this.lastSave = this.lastSave.then(async () => {
      let x = this.count++;
      console.log("start " + x);
      await axios.post("***",{});
      console.log("end " + x);
    });
  }

Is this a valid solution, or is there a better way?

Upvotes: 2

Views: 767

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

This pattern of thening the last promise is entirely valid. The only issue with what you currently have is error handling. In your current code if one request fails it will fail all future requests.

A more complete solution would be something like:

  lastSave = Promise.resolve();
  count = 0;
  async save() {
    const savePromise = this.lastSave.then(async () => {
      let x = this.count++;
      console.log("start " + x);
      await axios.post("***",{});
      console.log("end " + x);
    });
    // wait but don't fail forever on errors
    this.lastSave = savePromise.then(() => {}).catch(() => {});
    // You also need to return the promise so callers can react
    // to it. Note the lack of `.catch` here to not interfere with error handling
    return await savePromise; 
  }

Upvotes: 6

Related Questions