Promises - Code Exercises | CroCoder (2024)

Promises - Code Exercises | CroCoder (1)

Written by David Abram

Promises in JavaScript are an essential tool for managing asynchronous operations with ease and clarity. They assure that a certain piece of work will be done at a later time. This is incredibly useful for tasks that need to wait for something else to finish, like fetching data from a website.

Instead of juggling multiple callbacks, which can quickly become unwieldy and hard to follow, promises allow developers to chain operations in a linear and readable manner. This is done through .then() for successful operations, and .catch() for handling errors. This not only enhances code readability but also streamlines error handling, making the code more robust and maintainable.

Also take a look at these exercises:

  • JavaScript DOM
  • Callbacks
  • Map, Filter, Reduce
  • React Hooks

Contents

  • 50% of the time works 100% of the time
  • Chain some Math with Promises
  • Fetch data in parallel
  • The fastest response wins
  • Cancel a running Promise
  • ThePrimeagen's interview question

50% of the time works 100% of the time

Create a JavaScript Promise that, after a delay of 2 seconds, either resolves with the message "Hello World" or rejects with the error message "Error occurred".

The outcome (resolve or reject) should be determined by a random condition, ensuring a 50/50 chance of either occurring each time the code runs.

Helpful links

Input

randomPromise .then((message) => { console.log(message); }) .catch((error) => { console.error(error); });

Result

// 50% of the time console.logs"Hello World"// 50% of the time console.errors"Error occurred"
Solution(click to show)
const randomPromise = new Promise((resolve, reject) => { setTimeout(() => { // Randomly decide whether to resolve or reject const shouldResolve = Math.random() > 0.5; if (shouldResolve) { resolve("Hello World"); } else { reject("Error occurred"); } }, 2000);});randomPromise .then((message) => { console.log(message); }) .catch((error) => { console.error(error); });

The Promise is constructed with an executor function that invokes setTimeout to simulate a 2-second asynchronous operation.

Within the setTimeout callback, a random boolean shouldResolve is determined using Math.random() > 0.5. This expression has a 50% chance to evaluate a value as either true or false.

The Promise is resolved with "Hello World" if shouldResolve is true, and rejected with "Error occurred" if false. Promise.then() and Promise.catch() methods are attached to the Promise to handle its resolution and rejection, respectively.

Each execution of this code has an equal probability of either resolving or rejecting the Promise, demonstrating the handling of different Promise states in a single code structure.

Chain some Math with Promises

Input a number, double it, increase it by 10, and then multiply by 3.

Each operation should be in a separate Promise and then chained together.

Helpful links

Input

const value = 5;double(value) .then(addTen) .then(multiplyByThree) .then((result) => { console.log(result); });

Result

40
Solution(click to show)
const value = 5;const double = (value) => new Promise((resolve) => resolve(value * 2));const addTen = (value) => new Promise((resolve) => resolve(value + 10));const multiplyByThree = (value) => new Promise((resolve) => resolve(value * 3));double(value) .then(addTen) .then(multiplyByThree) .then((result) => { console.log(result); });

Each function returns a Promise that performs an arithmetic operation and resolves immediately.

The initial value is passed through the chain, undergoing each operation sequentially.

The final result is logged, demonstrating the cumulative effect of the chained operations.

Fetch data in parallel

Using fetchSimulator simulate fetching data from three different URLs in parallel.

Each "fetch" will be represented by a Promise that resolves after a delay taken from the delays array.

Use Promise.all to wait for all these Promises to resolve and then process the results.

Helpful links

Input

const delays = [800, 1200, 1000];const fetchSimulator = (url, delay) => { return new Promise(resolve => setTimeout(() => resolve(`Data from ${url}`), delay));};
Solution(click to show)
const delays = [800, 1200, 1000];const fetchSimulator = (url, delay) => { return new Promise(resolve => setTimeout(() => resolve(`Data from ${url}`), delay));};const data1 = fetchSimulator('https://crocoder.dev/data1', delays[0]);const data2 = fetchSimulator('https://crocoder.dev/data2', delays[1]);const data3 = fetchSimulator('https://crocoder.dev/data3', delays[2]);Promise.all([data1, data2, data3]) .then((responses) => { console.log('All data fetched:', responses); });

Three simulated fetch requests are created with different delays. Promise.all is used to wait for all these Promises to resolve.

Once all Promises resolve, their results are processed together, showcasing the ability of Promise.all to synchronize multiple asynchronous operations.

The fastest response wins

Using fetchSimulator simulate fetching data from three different URLs with a twist.

Each "fetch" will be represented by a Promise that resolves after a delay taken from the delays array.

Use Promise.race to get the fastest response!

Helpful links

Input

const delays = [800, 1200, 1000];const fetchSimulator = (url, delay) => { return new Promise(resolve => setTimeout(() => resolve(`Data from ${url}`), delay));};
Solution(click to show)
const delays = [800, 1200, 1000];const fetchSimulator = (url, delay) => { return new Promise(resolve => setTimeout(() => resolve(`Data from ${url}`), delay));};const data1 = fetchSimulator('https://crocoder.dev/data1', delays[0]);const data2 = fetchSimulator('https://crocoder.dev/data2', delays[1]);const data3 = fetchSimulator('https://crocoder.dev/data3', delays[2]);Promise.race([data1, data2, data3]) .then((response) => { console.log('This is the fastest response:', response); });

Each Promise is set to resolve after a different duration.

Promise.race() is used to wait for only the first Promise to resolve. Once the first Promise resolves, its result is processed.

This demonstrates how Promise.race() can be used to handle scenarios where only the first completion (or error) in a group of asynchronous operations is of interest.

Cancel a running Promise

Create a Promise that simulates a data fetching operation with a delay. Introduce a cancellation token that can be used to cancel the Promise before it resolves.

If the operation is cancelled, the Promise should reject with a "Cancelled" message; otherwise, it should resolve normally.

Cancel it!

Helpful links

Input

function createCancellationToken() { let cancel; const token = new Promise((_, reject) => { cancel = () => reject(new Error('Cancelled')); }); return { token, cancel };}const { token, cancel } = createCancellationToken();const fetchPromise = fetchData(token);// Simulate user cancellation after 1.5 secondssetTimeout(() => { cancel();}, 1500);fetchPromise .then(data => console.log(data)) .catch(error => console.error(error.message));
Solution(click to show)
function createCancellationToken() { let cancel; const token = new Promise((_, reject) => { cancel = () => reject(new Error('Cancelled')); }); return { token, cancel };}function fetchData(cancellationToken) { return new Promise((resolve, reject) => { setTimeout(() => { resolve("Data fetched"); }, 3000); cancellationToken.token.catch(() => { reject(new Error('Operation cancelled')); }); });}const { token, cancel } = createCancellationToken();const fetchPromise = fetchData({ token });// Simulate user cancellation after 1.5 secondssetTimeout(() => { cancel();}, 1500);fetchPromise .then(data => console.log(data)) .catch(error => console.error(error.message));

The createCancellationToken function is designed to generate a cancellation token along with a cancel function. This cancel function, upon invocation, leads to the rejection of the token's associated promise.

Concurrently, the fetchData function is structured to accept this cancellation token as a parameter, returning a Promise that signifies the ongoing data retrieval process.

Within fetchData, a delay is emulated through a timeout, and simultaneously, a monitoring mechanism is established on the cancellation token.

In scenarios where the token's promise faces rejection, i.e., is cancelled, the function takes action to both clear the data fetching timeout and reject the fetch promise.

This fetch promise embodies the asynchronous nature of the data-fetching task. The cancellation token is an integral part of this operation, as it is fed into the fetch promise.

In a typical flow, after a wait of 1.5 seconds, the cancel function is executed. This action triggers the rejection of the token's promise, consequently aborting the data fetch process.

To manage the outcomes of the fetch promise, the .then and .catch methods are employed for handling its resolved and rejected states, respectively.

ThePrimeagen's interview question

This exercise is a ThePrimeagen's interview question: Create an asynchronous request queue that manages the execution of tasks, ensuring that no more than three tasks run simultaneously.

Design a queue system that accepts promise factories (functions that return promises) and manages their execution. The queue should execute these promise factories but must limit the number of concurrently running tasks to three. When one task is completed, the next task in the queue should start.

Steps to implement

Implement a queue (can use an array for simplicity) to hold the promise factories.

Create a function to manage the execution of tasks. This function should handle the invocation of promise factories and maintain the count of concurrently running tasks.

Ensure that no more than three tasks are running at any given time. When a task is completed, the next task in the queue (if any) should start.

Create several promise factories that simulate async tasks with different durations.

Add these factories to the queue and test if the queue correctly limits the concurrency and processes tasks in the order they were added.

Helpful links

Solution(click to show)
class AsyncQueue { constructor(concurrencyLimit) { this.tasks = []; this.runningTasks = 0; this.concurrencyLimit = concurrencyLimit; } // Function to add tasks to the queue enqueue(task) { this.tasks.push(task); this.runNext(); } // Function to execute the next task runNext() { if (this.runningTasks < this.concurrencyLimit && this.tasks.length) { const task = this.tasks.shift(); this.runningTasks++; task().then(() => { this.runningTasks--; this.runNext(); }); } }}// Creating the queue with a concurrency limit of 3const queue = new AsyncQueue(3);// Promise factory functionconst createTask = (duration) => { return () => new Promise(resolve => { console.log(`Task started (Duration: ${duration}ms)`); setTimeout(() => { console.log(`Task completed (Duration: ${duration}ms)`); resolve(); }, duration); });};// Adding tasks to the queuefor (let i = 1; i <= 10; i++) { queue.enqueue(createTask(i * 1000));}

The AsyncQueue class manages and regulates task execution, maintaining a concurrency limit of no more than three tasks at any given time. This is achieved through its enqueue method, which plays a crucial role in adding new tasks to the queue. Once a task is enqueued, the enqueue method promptly invokes the runNext function to assess whether the task can be initiated immediately. The runNext method checks the current count of active tasks; if this count falls below the predefined concurrency limit, the method proceeds to launch the next task in line, simultaneously updating the count of running tasks.

Each task within this system is essentially a promise factory, designed to simulate an asynchronous operation. This is typically represented through the use of setTimeout, which allows each task to log both its initiation and completion, thereby mimicking the behavior of an asynchronous process. The completion of a task is a critical event, as it triggers the decrement of the running task count, creating room for additional tasks to be executed. Subsequently, the runNext method is called again to potentially initiate the next queued task, if available.

This entire mechanism, as embodied by the AsyncQueue class, exemplifies a prevalent and practical pattern in software development. It is particularly relevant in scenarios requiring meticulous management of asynchronous tasks, where the control over task execution and the limitation of concurrency are of paramount importance. The use of queues and promise factories in this context is not only effective but also illustrates a common approach to handling similar challenges in various programming environments.

Promises - Code Exercises | CroCoder (2024)

FAQs

What are promises in coding? ›

This feature is well established and works across many devices and browser versions. It's been available across browsers since July 2015. The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

How to practice promises in JavaScript? ›

A Promise contains both the producing code and calls to the consuming code:
  1. Promise Syntax. let myPromise = new Promise(function(myResolve, myReject) { ...
  2. Example. function myDisplayer(some) { ...
  3. Example Using Callback. setTimeout(function() { myFunction("I love You !!!"); }, 3000); ...
  4. Example Using Promise. ...
  5. Example using Callback.

What are promise methods? ›

Promise method is invoked when a promise is either resolved or rejected. It may also be defined as a carrier that takes data from promise and further executes it successfully. Parameters: It takes two functions as parameters. The first function is executed if the promise is resolved and a result is received.

What are the promises and how do they work? ›

In JavaScript, a Promise is an object that will produce a single value some time in the future. If the promise is successful, it will produce a resolved value, but if something goes wrong then it will produce a reason why the promise failed.

What are examples of promises? ›

Promise
  • I'll be here for your birthday. ...
  • Beth made a promise to Owen that she would look after his dog whenever he was away. ...
  • I promise I'll buy you another one.
  • I promise never to tell him.
  • The builder promised that he would be here on Tuesday.
  • I'll always remember you.
  • We'll send you the contract tomorrow.

What are the two types of promises? ›

There are two types of promises to give: conditional and unconditional.

Why do we use promises? ›

Promises provide a robust way to wrap the result of asynchronous work, overcoming the problem of deeply nested callbacks. The Promise object takes a callback function as a parameter, which, in turn, takes two parameters, resolve and reject. The promise is either fulfilled or rejected.

What is the syntax of Promise? ›

The constructor syntax for a promise object is: let promise = new Promise ( function ( resolve , reject ) { // executor (the producing code, "singer") } ) ; The function passed to new Promise is called the executor.

What is a Promise in JavaScript for dummies? ›

A promise in JavaScript is an object that represents the eventual completion or failure of an asynchronous operation. It is used for handling asynchronous operations, such as making API calls or reading files, in a more organized and readable way.

What are the 5 elements of the promise? ›

Foundations of the promise

The promise that Scotland made to care experienced children and young people is built on five foundations: family, voice, care, people and scaffolding.

What are the main rules of promise? ›

Important Promise Rules
  • A promise or “thenable” is an object that supplies a standard-compliant . ...
  • A pending promise may transition into a fulfilled or rejected state.
  • A fulfilled or rejected promise is settled, and must not transition into any other state.
Jan 22, 2017

Are JS promises hard? ›

In this article, I'm going to teach you one of the most confusing JavaScript topics, which is the Promise object. Promises may seem difficult at first, but they're actually quite simple once you understand how they work.

How do JavaScript promises work? ›

A promise is an object returned by an asynchronous function, which represents the current state of the operation. At the time the promise is returned to the caller, the operation often isn't finished, but the promise object provides methods to handle the eventual success or failure of the operation.

How to get result from promise in JavaScript? ›

To get the result of the successful promise execution, we need to register a callback handler using . then like this: const promise = new Promise(function(resolve, reject) { setTimeout(function() { const sum = 4 + 5; resolve(sum); }, 2000); }); promise. then(function(result) { console.

What are promises in API? ›

Promises are used to handle asynchronous operations in JavaScript. They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code.

Why do we use promises instead of callbacks? ›

Promises are generally better as they simplify code, avoid deep nesting, and provide better error handling with . then() and . catch() methods, unlike callbacks which can lead to difficult-to-read code.

What are promises in node? ›

What are Promises in Node. js? Promises are objects that represent the eventual completion or failure of an asynchronous operation. They provide a more structured way of handling asynchronous code compared to traditional callback functions.

What are promises and observables? ›

Both observables and promises help us work with asynchronous functionality in JavaScript. Promises deal with one asynchronous event at a time, while observables handle a sequence of asynchronous events over a period of time.

Top Articles
Meet Rumeysa Gelgi, the world's tallest woman, who's 7 feet tall and just traveled on a plane for the first time
Feet to Millimeters conversion: ft to mm calculator
Safety Jackpot Login
Roblox Roguelike
Pnct Terminal Camera
Brendon Tyler Wharton Height
Did 9Anime Rebrand
Www.megaredrewards.com
How do you mix essential oils with carrier oils?
Graveguard Set Bloodborne
Concacaf Wiki
Craigslist Phoenix Cars By Owner Only
Playgirl Magazine Cover Template Free
Conan Exiles Colored Crystal
How To Cut Eelgrass Grounded
Dutch Bros San Angelo Tx
U Break It Near Me
Petco Vet Clinic Appointment
Aldi Bruce B Downs
Iu Spring Break 2024
Bella Bodhi [Model] - Bio, Height, Body Stats, Family, Career and Net Worth 
Aes Salt Lake City Showdown
Teekay Vop
Munis Self Service Brockton
Hdmovie2 Sbs
2023 Ford Bronco Raptor for sale - Dallas, TX - craigslist
Pixel Combat Unblocked
Pronóstico del tiempo de 10 días para San Josecito, Provincia de San José, Costa Rica - The Weather Channel | weather.com
Jailfunds Send Message
Planned re-opening of Interchange welcomed - but questions still remain
Mercedes W204 Belt Diagram
Fedex Walgreens Pickup Times
Kltv Com Big Red Box
Teenbeautyfitness
Marine Forecast Sandy Hook To Manasquan Inlet
Prima Healthcare Columbiana Ohio
4083519708
Powerspec G512
Tal 3L Zeus Replacement Lid
New Gold Lee
Can You Buy Pedialyte On Food Stamps
Claim loopt uit op pr-drama voor Hohenzollern
Electric Toothbrush Feature Crossword
The best specialist spirits store | Spirituosengalerie Stuttgart
How to Connect Jabra Earbuds to an iPhone | Decortweaks
25100 N 104Th Way
Guy Ritchie's The Covenant Showtimes Near Look Cinemas Redlands
Maurices Thanks Crossword Clue
Pilot Travel Center Portersville Photos
Festival Gas Rewards Log In
Nfl Espn Expert Picks 2023
Turning Obsidian into My Perfect Writing App – The Sweet Setup
Latest Posts
Article information

Author: Duane Harber

Last Updated:

Views: 6434

Rating: 4 / 5 (51 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Duane Harber

Birthday: 1999-10-17

Address: Apt. 404 9899 Magnolia Roads, Port Royceville, ID 78186

Phone: +186911129794335

Job: Human Hospitality Planner

Hobby: Listening to music, Orienteering, Knapping, Dance, Mountain biking, Fishing, Pottery

Introduction: My name is Duane Harber, I am a modern, clever, handsome, fair, agreeable, inexpensive, beautiful person who loves writing and wants to share my knowledge and understanding with you.