Promise.all()
While working on my final Flatiron project, I had an issue where I needed the responses of several asynchronous tasks (fetches in my case) before moving forward with my code. I built an app that allows users to write their own pieces of interactive fiction. In the story editor component I set up the scene and path creation to create new scenes based on what the user enters in as paths. For example, a user could write a scene called “The Beginnning” that has three possible choices, “Enter the House,” “Search the Yard,” or “Run Away.” When the user is creating “The Beginning” these three scenes do not exist but the paths need their scene ids for backend persistence. I solved this issue using javascript’s Promise.all() method.
The Promise.all() method is best used in similar cases where the responses of multiple asynchronous tasks are required before other tasks can be completed. It takes an iterable, such as an Array, as an argument and, if the iterable contains promises, Promise.all() returns a pending promise that resolves to an array that contains the responses of all the promises in the iterable provided. This is best understood with an example, so I’ll walk you through my use case.
In my app, the user is creating stories with many scenes that are connected through paths. When a user starts a new story this new story is kept in state and has scenes added to it as they are created. Paths are an attribute of their scenes and stored as JSON data with their choice text and destination scene id.
Scene and path writing is set up as a form that updates the scene after the user fills out the form. Scenes are either created when a user clicks the “Add a Scene” button or when they make a path for a scene that doesn’t yet exist. When the user clicks submit, the program needs to do a few things. It will look at the paths the user created for the scene they wrote and search through the story in state to see if the destination scenes already exist. If they don’t the program will create them. Then, when all the destination scene ids are collected, the program will update the newly filled-out scene (the one the user is submitting) with those scene ids in the paths and render all the scenes for the story, including the empty scenes that were created when the user clicked submit.
In the image below I’ve started a story “Ladybug’s Adventure.” In the first scene, I’ve created three paths “Bathroom,” “Closet,” and “On Top of the Doors.” When I click submit, the steps I’ve outlined above will run.
When filling out the paths section of the form, the user can either select a scene from a drop down menu or type in a title to create a new scene. If the users selects an existing scene, I grab both the scene id and the choice text for the backend, but if the user types in a title, I have to create a new scene with that title before getting the scene id.
In the code above, I map over the paths that need newly created scenes and the return value, an array in this case, is set to “promises.” Promise.all is passed “promises” and then it runs another function “sceneUpdate” after all the fetches have been completed and all the paths are ready to be updated in the filled-out scene.
SceneUpdate then takes the complete paths and updates the scene to reflect the user’s changes and it then calls the function getNewScenes. The final step in this process is updating the scenes in state and rendering the page with all the scenes of the story.
In the image below, I’ve run this code with a few parts logged to the console. First, I logged the three scenes that needed to be created before “Where’s Ladybug?” can be updated. Then I logged the variable “promises” and all three scene promises were fulfilled. Then I logged paths after the three scenes were created and they now include their scene ids and all four scenes are rendered on the page.
Javascript’s Promise.all() method was invaluable to me in this process. I wanted the user to be able to create scenes when writing paths and this would have been much more difficult without this method.
Source: