Chapter 4 - Asynchronous Control Flow Patterns with Callbacks

0.0(0)
studied byStudied by 0 people
0.0(0)
full-widthCall Kai
learnLearn
examPractice Test
spaced repetitionSpaced Repetition
heart puzzleMatch
flashcardsFlashcards
GameKnowt Play
Card Sorting

1/9

encourage image

There's no tags or description

Looks like no tags are added yet.

Study Analytics
Name
Mastery
Learn
Test
Matching
Spaced

No study sessions yet.

10 Terms

1
New cards

Do not abuse in-place function definitions when defining callback. (What are the 3 callbacks discipline?)

These are some basic principles that can help us keep the nesting level low and

improve the organization of our code in general:

  • Exit as soon as possible. Use return, continue, or break, depending on the context, to immediately exit the current statement instead of writing (and nesting) complete if...else statements. This will help to keep our code shallow.

  • Create named functions for callbacks, keeping them out of closures and passing intermediate results as arguments. Naming our functions will also make them look better in stack traces.

  • Modularize the code. Split the code into smaller, reusable functions whenever possible.

2
New cards

Early return principle. (What it is in callback discipline?)

knowt flashcard image
3
New cards

Identifying reusable pieces of code

As a second optimization for our code function, we can try to identify reusable pieces of code. (img for exmaple)

Now that you know how to write clean asynchronous code using callbacks, we are ready to explore some of the most common asynchronous patterns, such as sequential and parallel execution.

<p>As a second optimization for our code function, we can try to identify reusable pieces of code.<em> (img for exmaple)</em></p><p>Now that you know how to write clean asynchronous code using callbacks, we are ready to explore some of the most common asynchronous patterns, such as sequential and parallel execution.</p>
4
New cards

Sequential execution

Executing a set of tasks in sequence means running them one at a time, one after the other. The order of execution matters and must be preserved, because the result of a task in the list may affect the execution of the next.

Sequential execution, despite being trivial when implemented using a direct style blocking API, is usually the main cause of the callback hell problem when using asynchronous CPS.

<p>Executing a set of tasks in sequence means running them one at a time, one after the other. The order of execution matters and must be preserved, because the result of a task in the list may affect the execution of the next.</p><p>Sequential execution, despite being trivial when implemented using a direct style blocking API, is usually the main cause of the callback hell problem when using asynchronous CPS.</p>
5
New cards

Executing a known set of tasks in sequence

The pattern described in the img works perfectly if we know in advance what and how many tasks are to be executed. This allows us to hardcode the invocation of the next task in the sequence, but what happens if we want to execute an asynchronous operation for each item in a collection? In cases such as this, we can't hardcode the task sequence anymore; instead, we have to build it dynamically.

<p>The pattern described in the img works perfectly if we know in advance what and how many tasks are to be executed. This allows us to hardcode the invocation of the next task in the sequence, but what happens if we want to execute an asynchronous operation for each item in a collection? In cases such as this, we can't hardcode the task sequence anymore; instead, we have to build it dynamically.</p>
6
New cards

Sequential iteration

The pattern described in the previous section works perfectly if we know in advance what and how many tasks are to be executed. This allows us to hardcode the invocation of the next task in the sequence, but what happens if we want to execute an asynchronous operation for each item in a collection? In cases such as this, we can't hardcode the task sequence anymore; instead, we have to build it dynamically.

<p>The pattern described in the previous section works perfectly if we know in advance what and how many tasks are to be executed. This allows us to hardcode the invocation of the next task in the sequence, but what happens if we want to execute an asynchronous operation for each item in a collection? In cases such as this, we can't hardcode the task sequence anymore; instead, we have to build it dynamically.</p>
7
New cards

The Sequential Iterator pattern

Execute a list of tasks in sequence by creating a function named iterator, which invokes the next available task in the collection and makes sure to invoke the next step of the iteration when the current task completes.

8
New cards

Iterating while applying an asynchronous operation. (The Sequential Iterator pattern)

The code of the spiderLinks() function from the previous section is a clear example of how it's possible to iterate over a collection while applying an asynchronous operation.

You may also notice that it's a pattern that can be adapted to any other situation where we need to iterate asynchronously over the elements of a collection or, in general, over a list of tasks.

to address several common needs. Just to mention some examples:

  • We can map the values of an array asynchronously.

  • We can pass the results of an operation to the next one in the iteration to implement an asynchronous version of the reduce algorithm.

  • We can quit the loop prematurely if a particular condition is met

    (asynchronous implementation of the Array.some() helper).

  • We can even iterate over an infinite number of elements.

<p>The code of the spiderLinks() function from the previous section is a clear example of how it's possible to iterate over a collection while applying an asynchronous operation. </p><p>You may also notice that it's a pattern that can be adapted to any other situation where we need to iterate asynchronously over the elements of a collection or, in general, over a list of tasks.</p><p>to address several common needs. Just to mention some examples:</p><ul><li><p>We can map the values of an array asynchronously.</p></li><li><p>We can pass the results of an operation to the next one in the iteration to implement an asynchronous version of the reduce algorithm.</p></li><li><p>We can quit the loop prematurely if a particular condition is met</p><p>(asynchronous implementation of the Array.some() helper).</p></li><li><p>We can even iterate over an infinite number of elements.</p></li></ul><p></p>
9
New cards

Parallel execution

There are some situations where the order of execution of a set of asynchronous tasks is not important, and all we want is to be notified when all those running tasks are completed. Such situations are better handled using a parallel execution flow.

In Node.js, synchronous (blocking) operations can't run concurrently unless their execution is interleaved with an asynchronous operation, or interleaved with setTimeout() or setImmediate().

<p>There are some situations where the order of execution of a set of asynchronous tasks is not important, and all we want is to be notified when all those running tasks are completed. Such situations are better handled using a parallel execution flow.</p><p>In Node.js, synchronous (blocking) operations can't run concurrently unless their execution is interleaved with an asynchronous operation, or interleaved with setTimeout() or setImmediate().</p>
10
New cards