📜 ⬆️ ⬇️

Promises on the example of a burger party



This is a translation of an article that Mariko Kosaka wrote as an alternative introduction to JavaScript promises. She sketched illustrations in her notebook while reading various articles about promises. If you want to study in more detail, at the end you will find a list of useful links.

Recently, Mariko participated in the discussion of how to use JavaScript to make a feature that would give access to external data (should have been asynchronous). She said: "Well, let's use fetch() ... so in the code ... uh ...", and while trying to recall the fetch API, the interlocutor said: "The promise will return." According to Mariko, her brain fell into a stupor, and she said: "Honestly, I do not know what you mean ..."
')
She had to write the code based on promises many times, but for a complete picture the necessary puzzles in her head were for some reason not connected. She realized that she really did not “enter” the essence.

I can't even describe how difficult it is to explain this expression: “Promise will return”
But this is probably because I do not understand what “promis” is.
- Mariko Kosaka (@kosamari) January 13, 2017

If you look through her twitter , you will see that she uses visual images when learning, and for this draws the concepts used in the code in the form of physical metaphors. So she tries to cope with a double level of abstraction (programming language and English as a second language). Therefore, she had to turn to drawing this time too.

Here is a snippet of code that will be used for an example.

 //   function cookBurger (type) { ... } //   function makeMilkshake (type) { ... } //  ,    function order (type) { return new Promise(function(resolve, reject) { var burger = cookBurger(type) burger.ready = function (err, burger) { if (err) { return reject(Error('Error while cooking')) } return resolve(burger) } }) } order('JakeBurger') .then( burger => { const milkshake = makeMilkshake('vanila') return { burger: burger, shake: milkshake } }) .then( foodItems => { console.log('BURGER PARTY !', foodItems) }) .catch( err => { console.log(err) }) 

Let's arrange a burger party


Welcome to Promise Square Park, where JakeShack is located. Her burgers are very popular, but the number of cash registers for placing orders is limited, so the queue of customers at the counter is always large. However, excellent chefs work in the kitchen and are capable of simultaneously preparing several orders.

If anything, then the prototypes were Madison Square Park and ShakeShack in New York. There is very tasty food, and the queue is always long.

Promysifikatsiya action


To take orders as quickly as possible, JakeShack uses a signaling system. When a customer pays for an order, the cashier issues a tray and device alarm in exchange for a payment.



The tray is a JakeShack promise to the customer that there will be a tasty burger on the tray as soon as it is ready, and the alarm shows the status of the order. If he is silent, the order is processed (pending) - the cooks in the kitchen are busy working on your order. When the screen glows red and a beep sounds, it means that the order has been settled .

A small nuance associated with the state of " assembled ." This is not a synonym for "ready." This means that the order was processed in the kitchen and the buyer needs to decide what to do with it next. You (the buyer) will probably want to pick up an order at the counter, but it is also possible that you simply leave. The decision is yours.

Let's take a look at the code. When you call the order function, it “returns promise” (gives you a tray with a signaling device). The return value (burger) should appear on the tray when promise is executed and the callback function is called.



Add Promise Handlers


It seems that the alarm has rung, which means that you need to go to the counter and ask for your order. Further, there are two possible scenarios.



  1. The order is ready (promise completed). Hooray! Your order is ready and the cook hands you a fresh, tasty-smelling burger. Promise done!
  2. Order not ready (promis rejected). It seems the burgers are out of the kitchen, so the burger promise was not done. Get paid!

Here's how to prepare for both situations.



.then() takes another function as the second argument, which can also be used as a handler for the reject. For simplicity, I only used .catch() . If you want to know more about how both options are handled, read this article: https://developers.google.com/web/fundamentals/getting-started/primers/promises#error_handling .

Chain of promises (cheining)


Suppose your order was ready, but you decided that for a burger party you still need a milkshake. So, you are on the C-line (a separate line for drinks is actually used in ShakeShack for more efficient order management). When you order your cocktail, the cashier gives you a different tray and a different alarm. And since the milkshake is prepared very quickly, the cashier immediately issues it, along with a tray. No need to wait for the alarm device to ring (it already does it!).



Now let's see how our code works. The promise chain is simply adding a new .then() to the code. The value returned by .then() is always a promise. Just remember that each .then() returns you a tray and a signaling device, and the actual return value is passed as an argument to the callback function.



Now you have a burger and a milkshake, you are ready for a BURGER PARTY!

Extra tricks!


The promises have a couple more methods that allow you to perform cool tricks.

Promise.all() creates a promise that takes an array of promises (elements) as an argument. This promise is performed when all its elements are completed. Suppose you ordered 5 different burgers for your friends, but you do not want to go and pick them up one by one all 5 times, and then when they are all ready. In this case, a good solution is Promise.all() .

Promise.race() is similar to Promise.all() , but the promise is considered completed or rejected as soon as at least one of its elements is completed or rejected. This behavior allows you to emulate a try-and-grab scheme (try and grab). If you are incredibly hungry, you can order a burger, cheeseburger and hot dog at the same time, but take what comes first from the kitchen. But in that case, if, for example, the kitchen was closed or for some reason it stopped working, and the first thing rejects the burger promis, then the whole promis will be rejected.

You can also read more about promises:

Source: https://habr.com/ru/post/323066/


All Articles