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.
    

I have created a set of resources for learning asynchronous JavaScript. These guides—Callbacks, Promises, and Async/Await —cover everything I’ve learned from years of real-world JavaScript experience.

If you found this article helpful, you’ll get so much out of these guides. Each one is optimized for those “lightbulb moments,” building a strong mental model for how asynchronous JavaScript works and how you can use it to create fast, dynamic applications.