web_api_cookbook_introductuction

Web API Cookbook Introduction

Introduction

“A lot of the APIs covered in this book are asynchronous. When you call one of these functions or methods, you might not get the result back right away. Different APIs have different mechanisms to get the result back to you when it’s ready.” (WbAPICook 2024)

Callback Functions

The most basic asynchronous pattern is a callback function. This is a function that you pass to an asynchronous API. When the work is complete, it calls your callback with the result. Callbacks can be used on their own or as part of other asynchronous patterns.

Events

Many browser APIs are event based. An event is something that happens asynchronously. Some examples of events are:

A button was clicked.

The mouse was moved.

A network request was completed.

An error occurred.

An event has a name, such as click or mouseover, and an object with data about the event that occurred. This might include information such as what element was clicked or an HTTP status code. When you listen for an event, you provide a callback function that receives the event object as an argument.

Objects that emit events implement the EventTarget interface, which provides the addEventListener and removeEventListener methods. To listen for an event on an element or other object, you can call addEventListener on it, passing the name of the event and a handler function. The callback is called every time the event is triggered until it is removed. A listener can be removed manually by calling removeEventListener, or in many cases listeners are automatically removed by the browser when objects are destroyed or removed from the DOM.

Promises

Many newer APIs use Promises. A Promise is an object, returned from a function, that is a placeholder for the eventual result of the asynchronous action. Instead of listening for an event, you call then on a Promise object. You pass a callback function to then that is eventually called with the result as its argument. To handle errors, you pass another callback function to the Promise’s catch method.

A Promise is fulfilled when the operation completes successfully, and it is rejected when there’s an error. The fulfilled value is passed as an argument to the then callback, or the rejected value is passed as an argument to the catch callback.

There are a few key differences between events and Promises:

Event handlers are fired multiple times, whereas a then callback is executed only once. You can think of a Promise as a one-time operation.

If you call then on a Promise, you’ll always get the result (if there is one). This is different from events where, if an event occurs before you add a listener, the event is lost.

Promises have a built-in error-handling mechanism. With events, you typically need to listen for an error event to handle error conditions.

Working with Promises

Problem

You want to call an API that uses Promises and retrieve the result.

Solution

Call then on the Promise object to handle the result in a callback function. To handle potential errors, add a call to catch.

Imagine you have a function getUsers that makes a network request to load a list of users. This function returns a Promise that eventually resolves to the user list (see Example 1-1).

Example 1-1. Using a Promise-based API

getUsers() .then( // This function is called when the user list has been loaded. userList ⇒ { console.log('User List:'); userList.forEach(user ⇒ { console.log(user.name); }); } ).catch(error ⇒ { console.error('Failed to load the user list:', error); });

Discussion

The Promise returned from getUsers is an object with a then method. When the user list is loaded, the callback passed to then is executed with the user list as its argument.

This Promise also has a catch method for handling errors. If an error occurs while loading the user list, the callback passed to catch is called with the error object. Only one of these callbacks is called, depending on the outcome.

Always Handle Errors

It’s important to always handle the error case of a Promise. If you don’t, and a Promise is rejected, the browser throws an exception for the unhandled rejection and could crash your app.

To prevent an unhandled rejection from taking down your app, add a listener to the window object for the unhandledrejection event. If any Promise is rejected and you don’t handle it with a catch, this event fires. Here you can take action such as logging the error.

Loading an Image with a Fallback

Problem

You want to load an image to display on the page. If there’s an error loading the image, you want to use a known good image URL as a fallback.

Solution

Create an Image element programmatically, and listen for its load and error events. If the error event triggers, replace it with the fallback image. Once either the requested image or the placeholder image loads, add it to the DOM when desired.

For a cleaner API, you can wrap this in a Promise. The Promise either resolves with an Image to be added or rejects with an error if neither the image nor the fallback can be loaded (see Example 1-2).

Example 1-2. Loading an image with a fallback

/**

  • Loads an image. If there's an error loading the image, uses a fallback * image URL instead. * * @param url The image URL to load * @param fallbackUrl The fallback image to load if there's an error * @returns a Promise that resolves to an Image element to insert into the DOM */ function loadImage(url, fallbackUrl) { return new Promise1)
1)
resolve, reject) ⇒ { const image = new Image(); // Attempt to load the image from the given URL image.src = url; // The image triggers the 'load' event when it is successfully loaded. image.addEventListener('load', () ⇒ { // The now-loaded image is used to resolve the Promise resolve(image); }); // If an image failed to load, it triggers the 'error' event. image.addEventListener('error', error ⇒ { // Reject the Promise in one of two scenarios: // (1) There is no fallback URL. // (2) The fallback URL is the one that failed. if (!fallbackUrl ]] | web_api_cookbook_introductuction | Discussion If you have multiple tasks that don’t depend on one another, Promise.all is a good choice. Example 1-6 calls getUser three times, passing a different user ID each time. It collects these Promises into an array that is passed to Promise.all. All three requests run in parallel. Promise.all returns another Promise. Once all three users have loaded successfully, this new Promise becomes fulfilled with an array containing the loaded users. The index of each result corresponds to the index of the Promise in the input array. In this case, it returns an array with users 1, 2, and 3, in that order. What if one or more of these users failed to load 2024) ==Fair Use Sources== Fair Use Sources:
web_api_cookbook_introductuction.txt · Last modified: 2025/02/01 06:22 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki