McDonald’s Order Promise Analogy

From the JavaScript course I am doing now:

A Promise is like placing an order at a restaurant. You receive a ticket (Promise object) that indicates your order is being processed. The order can either be successfully delivered (resolved) or canceled (rejected), and you can attach actions (.then() and .catch()) to handle either outcome.

I changed the analogy a little, added some more details and asked AI to finish it. Here’s the end result:

1. Place an order at McDonald’s and receive a buzzer.

  • This is creating a new Promise – it represents a future value.
  • The buzzer (Promise) is now in a pending state.

2. Waiting for food preparation happens in the background.

  • This is an asynchronous operation like ⁠setTimeout() or an API call.
  • The kitchen staff (JavaScript engine) is working on your order without blocking other customers.

3. When food is ready, the employee pushes a button to make your buzzer go off.

  • This is the Promise’s state changing to fulfilled.
  • The ⁠resolve() function is called by the code handling the async operation.

4. The prepared food is handed to you when you return to the counter.

  • This is the data that the Promise resolved with.
  • The value passed to ⁠resolve() becomes available in the ⁠.then() handler.

5. If they’re out of fries or there’s a problem with your order, the manager comes to your table to explain the issue.

  • This is the Promise’s state changing to rejected.
  • The ⁠reject() function is called with an error reason.

6. The explanation of what went wrong (e.g., “We’re out of fries”) is the error information.

  • This is the error data that the Promise rejected with.
  • The value passed to ⁠reject() becomes available in the ⁠.catch() handler.

7. You deciding what to do next after getting your food or hearing about the problem.

  • This is your code in the ⁠.then() or ⁠.catch() handlers executing.
  • You might be satisfied with your food or order something else instead.

8. Once you’ve either received your food or dealt with the problem, your interaction with that specific order is complete.

  • The Promise is now in a settled state (either fulfilled or rejected).
  • A Promise can never change state again after being settled.

This analogy covers all three possible states of a Promise:

  • Pending: Order placed, waiting for food
  • Fulfilled: Food ready and delivered
  • Rejected: Order cannot be completed due to a problem

In code form

const orderFood = menuItem => {
	return new Promise((resolve, reject) => {
		console.log(`Order for ${menuItem} received. Please wait...`);

		// Simulate food preparation (async operation)
		setTimeout(() => {
			// Randomly succeed or fail the order
			if (Math.random() > 0.2) {
				// Food prepared successfully
				const food = `🍔 Fresh ${menuItem}`;
				resolve(food); // Promise fulfilled
			} else {
				// Something went wrong
				reject(`Sorry, we're out of ${menuItem}`); // Promise rejected
			}
		}, 2000);
	});
};

// Using the Promise
orderFood('fries')
	.then(food => {
		console.log(`Enjoy your ${food}!`);
	})
	.catch(problem => {
		console.log(`Order failed: ${problem}`);
	})
	.finally(() => {
		console.log("Thank you for visiting McDonald's");
	});

Execution Flow Breakdown

1. When ⁠orderFood('fries') is called:

  • The function is executed immediately
  • A new Promise object is created
  • The executor function (the function passed to the Promise constructor) runs synchronously

2. Inside the executor function:

  • console.log(Order for ${menuItem} received. Please wait...⁠) executes immediately
  • setTimeout() is called, which schedules the callback to run later
  • The Promise object is returned to the caller (still in pending state)

3. After the Promise is returned:

  • The ⁠.then() and ⁠.catch() handlers are attached to the Promise
  • These handlers are not executed yet – they’re just registered to run later

4. When the timeout completes (after 2000ms):

  • The timeout callback runs
  • Either ⁠resolve() or ⁠reject() is called
  • This changes the Promise state to fulfilled or rejected
  • The appropriate handler (⁠.then() or ⁠.catch()) is queued to run in the next event loop iteration

When the promise is fulfilled:

When the promise is rejected:

Addendum

The most confusing part to me was what resolve and reject functions are. Where are they defined? What is their definition?

My notes:

resolve and reject are the names we usually give to these parameters. They can be anything else just like any other function’s arguments.

The ⁠resolve and reject functions are provided by the JavaScript engine when you create a new Promise – more specifically, the constructor() function of the Promise class. They are automatically passed to the executor function (the function you provide to the Promise constructor).

The Promise constructor signature looks like this:

new Promise(executor);

where ⁠executor is a function with this signature:

function executor(resolveFunction, rejectFunction) {
    // Your code here
}

The ⁠resolve and reject functions are internal functions provided by the JavaScript engine.

While you can’t see its actual implementation, conceptually the resolve function:

  1. Changes the state of the Promise from “pending” to “fulfilled”
  2. Sets the Promise’s result value to whatever you pass to it
  3. Schedules any attached ⁠.then() callbacks to run in the next event loop iteration

Another example

The Promise constructor provides two parameters to the executor function. It is up to you whether you use just one (as resolve) or both (resolve and reject).

const wait = milliseconds => {
    return new Promise((resolve, reject) => {
        // Validate input
        if (typeof milliseconds !== 'number' || milliseconds < 0) {
            reject(new Error('milliseconds must be a positive number'));
            return;
        }
        
        // Set up the timer
        setTimeout(() => {
            resolve('Timer completed!'); // Can pass a value
        }, milliseconds);
    });
}

// Usage
wait(1000)
    .then(message => console.log(message)) // "Timer completed!"
    .catch(error => console.error(error));

You can pass a value to ⁠resolve() which becomes available in the ⁠.then() callback.

When you call ⁠new Promise(), the JavaScript engine:

  1. Creates a new Promise object in “pending” state
  2. Creates two special functions (commonly called ⁠resolve and ⁠reject)
  3. Calls your executor function with these two functions as arguments
  4. When you call ⁠resolve(), it triggers the Promise’s internal state change
Get access to all 558 Bricks code tutorials with BricksLabs Pro

Leave the first comment

 

Related Tutorials..

Pro
Opening Submenus with Click Instead of Hover in Bricks

Opening Submenus with Click Instead of Hover in Bricks

This Pro tutorial provides the code for opening submenus with click instead of hover in Bricks. Step 1 Add this in child theme's style.css: Step…
Categories:
Pro
[WooCommerce] Sticky on Scroll Add to Cart section in Bricks

[WooCommerce] Sticky on Scroll Add to Cart section in Bricks

Setting up a sticky section that fades in when scrolling down and fades away when scrolled to the top.
Categories:
Pro
tsParticles in Bricks

tsParticles in Bricks

Updated on 5 Aug 2023 This Pro tutorial provides the steps to set up tsParticles, a lightweight TypeScript (uses JavaScript) library for creating particles as…
Categories:
Enqueueing a JavaScript File in Bricks

Enqueueing a JavaScript File in Bricks

Bricks child theme's functions.php comes with code to enqueue (load) style.css on the front end. What if you want to load a custom JavaScript file…
Categories:
Pro
Grid.js in Bricks

Grid.js in Bricks

This Pro tutorial provides the steps to use Grid.js in a WordPress site powered by Bricks builder. Grid.js is a lightweight and performant JavaScript library…
Categories:
How to disable smooth scroll in Bricks

How to disable smooth scroll in Bricks

In certain situations like using ScrollSmoother, you may be looking to disable smooth scrolling functionality that’s built into Bricks.
Categories:
Pro
Switching Tabs on Hover in Bricks

Switching Tabs on Hover in Bricks

This Pro tutorial shows how to make the tabs of Tabs (Nestable) elements active on hover in Bricks. Step 1 Add one or more Tabs…
Categories: