What's Fetch? What Makes it... Happen?

A very minimal deep dive into promises and code stacks

ยท

5 min read

Joining Flatiron and embarking on a new coding journey has been an exhilarating yet slightly overwhelming experience. While some coding concepts, like assigning variables, are relatively straightforward. However running your first, several, fetch requests seem to require a bit of blind faith. When I first encountered fetch all I could think of was how I'd embody Gretchen Wieners from Mean Girls, who kept "trying to make 'Fetch' happen." Trust me, it's gonna happen.

To make fetch happen within your code, it's essential to understand how it functions in web development. In this blog post, let's unravel the mystery of a promise in JavaScript. These little code pinky swears not only make your code cleaner but also assist the browser in managing tasks smoothly.

Asynchronous Operations

Imagine this scenario: you're browsing the internet for your favorite Mean Girls meme. However, the webpage you're using keeps freezing up as you attempt to load the next page of memes. You click buttons repeatedly, trying to get some kind of interaction from the page, until it finally startles into action, immediately trying to respond to every click you just made. No one wants this, the user or developer. To solve this we can use asynchronous operations. They allow the website's code to run smoothly while certain tasks, like fetching all those memes from the API, happen in the background instead of blocking the rest of the webpage from doing anything.

Meet the Promise

A Promise in JavaScript is an object representing an asynchronous operation's eventual completion or failure. Think of it like a little helper saying, "Hey, I'm working on something, and when I'm done, I promise I'll let you know if it worked out or not." It has three states: pending (still working), fulfilled (yay, it worked!), and rejected (uh-oh, something went wrong).

Callback Queue โ€“ Where Promises Hang Out

When your Promise finishes its task, it doesn't make a grand entrance. Instead, it joins the callback queue, patiently waiting for its turn to return to the stage (call stack) and share the results. This offloading of a Promise is what allows for the execution of other tasks while the promise is in progress, preventing any blocking and ensuring a smooth and responsive user experience.

Understanding the Event Loop

The event loop is a browser-based event handler that executes one task at a time by continuously checking between the call stack and the callback queue for tasks to move to the call stack. Think of it as the person who has to unstack two piles of boxes.

Here's a breakdown:

  1. Call Stack: This is where synchronous code executes. Each function call creates a box, and the boxes are stacked on top of each other.

  2. Web APIs and Promises: When you encounter asynchronous operations like Fetch, they are offloaded to Web APIs.

  3. Callback Queue: Once an asynchronous task is complete, it doesn't immediately jump back into the call stack. Instead, it goes to the callback queue.

  4. Event Loop: The event loop continually checks the call stack. If it's empty, it takes the first task from the callback queue and pushes it onto the call stack.

Below is a gif that shows three asynchronous functions being called. They're complete, they get stacked in the Callback 'Task' Queue and then get moved to the Call Stack. If you want a more thorough explanation, please visit Loupe.

[censor output image]

What To Do With a Promise

Think of .then() and .catch() as your Promise's way of saying, "When I'm done, come here and do this next!" These methods help you organize your code in a way that's easy to follow, eliminating the confusion of nested callbacks. The beauty of them is that you can link multiple .then() blocks together, creating a clear flow in your code. Simpler is always better, so multiple .then() blocks are better than one dense and overcomplicated one.

Fetching Memes with Fetch

Let's see how fetch makes fetching memes a breeze:

fetch('https://example.com/memes')
//Promise was made, awaiting response
  .then(response => response.json())
  .then(data => {
    // Process the fetched data
    console.log('I got the memes:', data);
  })
  .then(data => { 
    //More processing of data
    console.log('I ALSO got the memes:', data);

When this code is run, it makes a fetch request to https://example.com/memes and it returns the data caught by .then() assining the data array to 'data'. You can then have as many subsequent .then()'s as you'd like. However if you stop referencing 'data' then the promise chain is broken. For example:

fetch('https://example.com/memes')
//Promise was made, awaiting response
  .then(response => response.json())
  .then(data => {
    // Process the fetched data
    console.log('I got the memes:', data);
  })
  .then(data => { 
    //More processing of data
    console.log('I ALSO got the memes:', data);
  .then((/*  NO INPUT  */) => { 
    //Responding to the promise event, but doesn't need data
    console.log('I did not get memes');
  .then(data => { 
    //Tries to process data
    console.log(('I tried to get memes:', data);

This code will run the same as the first, up until the final line, where it will throw an ERROR since the final .then() never actually get access to the 'data' since the prior .then() didn't use it.

Conclusion

Congratulations! You've taken your first steps into the world of JavaScript fetch requests. Hopefully they have been demystified and the promise is more than just a vague concept. These are tools that should't confuse you but instead help you create amazing things on the web. Isn't that so fetch?

I told you fetch was gonna happen.

ย