Promises Aren't Just for Fetching Data: Learn Other Uses

You’ve probably seen promises used to call an API and get data. But you’ve never seen them used anywhere else, and now you’re wondering: Are promises only used for fetching data? It’s a common question, especially when you're new to JavaScript.

The answer is no—promises are much more versatile than that! A promise represents an eventual result. It’s useful for anything you expect to eventually happen. Fetching data is a common example because you expect to eventually receive data, but it’s by no means the only use case.

Here are some examples where promises can be incredibly handy:

  • Reading Files

    Imagine you’re building a Node.js app, and you need to read a file. This takes time, and you don’t want your whole program to pause while it waits. You can use a promise to handle this. Here’s how it looks:

    import { readFile } from "fs/promises";
    
    const result = await readFile("./someFile.txt");
    
  • Waiting for a Set Amount of Time

    Sometimes, you need to pause your code for a bit. While you could use setTimeout for this, wrapping it in a promise can be useful, especially if you want to coordinate it with other promises.

    For example, you might use a promise to cancel an operation if it takes too long:

    try {
      const result = await Promise.race([
        fetch("someUrlThatMightTakeAWhile"),
        new Promise((resolve, reject) => {
          setTimeout(() => reject("timed out"), 5000);
        }),
      ]);
    } catch (error) {
      // If we get here, then either an error occurred in fetch, or 5 seconds passed.
    }
    
  • User Interaction

    Let’s say you want to show a confirmation dialog before moving forward with an action. Promises can help here too. If the user confirms, the promise resolves, and you continue; if they cancel, the promise rejects:

    const doSomethingImportant = async () => {
      try {
        await showConfirmationDialog();
        // If we get here, the user confirmed
        doStuff();
      } catch (error) {
        // User aborted
      }
    };
    
    const showConfirmationDialog = () => {
      return new Promise((resolve, reject) => {
        // Code to create a dialog with confirm and cancel buttons
        confirmButton.addEventListener("click", resolve);
        cancelButton.addEventListener("click", reject);
      });
    };
    
  • Waiting for an Event

    Events happen all the time in web development. For instance, you might want to load a script and only move forward once it’s fully loaded. A promise can keep track of this:

    const loadScript = (source) => {
      return new Promise((resolve, reject) => {
        const script = document.createElement("script");
        script.src = source;
        script.addEventListener("load", resolve);
        script.addEventListener("error", reject);
        document.body.appendChild(script);
      });
    };
    
    await loadScript("someScript.js");
    // When we get to this line, the script has loaded.
    

Get my free, weekly JavaScript tutorials

Want to improve your JavaScript fluency?

Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.

Join today, and level up your JavaScript every Sunday!

Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.

- Remi Egwuda