Chapter 15: Isolating timelines
The introduction presents timeline diagrams as a way to see actions over time and reason about bugs, especially in distributed systems.
After this chapter you will be able to
- Purpose of timeline diagrams. Explain that timeline diagrams represent sequences of actions over time, helping developers understand how software runs and diagnose or predict bugs, particularly in distributed systems.
- Click-speed-dependent cart bug. Describe the reported mismatch between the shopping cart total and the checkout charge, and explain why a slow clickthrough does not reproduce the problem.
- Fast-click bug behavior. Describe how clicking the buy button twice quickly reproduces the bug: repeated attempts to add shoes twice produce different totals, and only $14 is correct.
- Limits of sequential views. Explain why reading the code and use case diagram does not account for the fast-click bug: they look correct, and the system behaves correctly when clicks are spaced out, but they do not show what happens when two operations run at the same time.
- Timelines and their diagrams. Explain that a timeline is a sequence of actions over time and that a timeline diagram shows that sequence graphically. Describe how placing timelines side by side can reveal actions that interact or interfere.
- Sequential actions in one timeline. Explain that actions known to occur in order go one after another in the same timeline, while calculations can be omitted because their results do not depend on when they run.
- Uncertain actions in separate timelines. Explain that actions that can happen at the same time or in either order belong in separate, side-by-side timelines; asynchronous callbacks are one way this situation arises.
- Increment and assignment actions. Explain why total++ and total+=3 each produce two actions in a timeline diagram when total is global, even though each expression is short.
- Argument evaluation order. Describe the order of actions when a function call uses an expression as an argument, such as logging a global variable.
- Add-to-cart action identification. Describe the first step in drawing the add-to-cart timeline: mark the actions in the code and ignore calculations. Note that the code also contains callbacks passed to cost_ajax() and shipping_ajax(), without explaining how to draw them.
- Asynchronous callback timelines. Explain that asynchronous callbacks happen in a new timeline, so the order in which lines execute can differ from the order in which they are written.
- Asynchronous Callback Timelines. Explain why an asynchronous input/output callback creates a new timeline in JavaScript.
- Multithreaded Ordering And Locks. Describe how new threads create timelines, why their actions are difficult to order, and what locks control.
- Placing actions on timelines. Trace how the section places actions from the JavaScript code onto a timeline diagram: code outside callbacks stays on the original timeline, while asynchronous callbacks get new timelines.
- Drawing the add-to-cart timeline. Describe how to draw the identified add-to-cart actions on a timeline diagram: place them in order and start a new timeline for each asynchronous callback.
- Interleavable and uninterrupted actions. Explain the two kinds of sequential code shown in a timeline diagram: actions that may have another timeline's action run between them, and actions that cannot. Describe how separate boxes connected by a line differ from multiple actions in one box.
- Parallel timeline orderings. Explain that side-by-side timelines represent parallel code, not a guarantee that their actions happen at the same time. Describe the three possible orderings of two actions and why a reader must consider them even when diagrams align the actions differently.
- Number of timelines. Explain why fewer timelines make a system easier to understand, even though threads, asynchronous callbacks, and client-server communication often require multiple timelines.
- Length of each timeline. Explain how eliminating steps from timelines reduces the number of possible orderings.
- Shared resources across timelines. Distinguish reducing shared resources from reducing possible orderings: explain why steps on different timelines need less ordering analysis when they do not share resources.
- Synchronous actions on one thread. Explain why synchronous JavaScript actions do not need separate timeline boxes for possible interleavings, contrasting this with two Java threads updating a shared variable.
- Asynchronous timing uncertainty. Explain why asynchronous calls make timeline ordering a concern again in JavaScript, despite its single main thread.
- Sequential job processing. Explain how the event loop processes the job queue: it takes one job, runs it to completion, and then takes the next, so two jobs do not run at the same time.
- Event jobs and callbacks. Describe what causes a job to be added to the queue and what the job contains. Explain how the event loop uses its callback and event data.
- Asynchronous request ordering. Trace what happens after JavaScript initiates an AJAX request: it is queued for the networking engine, the code continues without waiting, and responses can arrive out of order, adding callbacks to the job queue out of order.
- Response event callbacks. Explain how code receives an AJAX response by registering event callbacks, including what the load and error events indicate.
- Buy Button Asynchronous Timeline. Trace the buy button’s sequence from registering a click callback through the queued click job, AJAX request, and later completion callback. Describe what each callback changes on the page.
- Single Timeline Action Consolidation. Explain why actions on one JavaScript timeline can be consolidated and how that changes the diagram.
- Certain and uncertain orderings. Explain which actions in the finished diagram have a guaranteed order and which may vary. Describe how JavaScript’s single thread limits the possible orderings of the two AJAX callbacks.
- Correctness across possible orderings. Explain how possible action orderings can be used to judge whether code has a timing bug, and apply that test to the loading spinner in this section.
- Ordered JavaScript timeline simplifications. Describe the two simplifications in order: combine actions on each timeline into one box, then combine timelines that end by starting one new timeline. Explain why JavaScript’s single thread permits the first simplification and how AJAX callbacks permit the second.
- Preserved interleaving in boxes. Explain why the resulting single timeline must still show separate boxes rather than merging every action into one box.
- Three diagramming steps. Describe the three steps used to make the timeline diagram: identify actions, draw them according to whether they are sequential or parallel, and simplify the result.
- JavaScript timeline simplification. Explain how JavaScript’s single-threaded model and asynchronous callbacks let the example’s diagram be consolidated, and why separate boxes are still needed.
- Atomic actions on timelines. Describe how to identify the actions for a timeline diagram by breaking composite actions down to atomic reads and writes, including operations such as ++ and +=.
- Sequential and parallel timelines. Explain how to place actions on the same or separate timelines based on whether their execution is ordered or can occur in parallel, and how dotted lines show constraints between them.
- Timeline simplification and reading. Describe the section’s guidelines for simplifying a timeline diagram and evaluating the possible orders of actions on different timelines.
- Two-click timeline comparison. Explain why the cart-update timeline must be shown twice to examine rapid clicks, and describe the ordering constraint shown between the two clicks.
- Slow-click timeline ordering. Explain that stretching the lines between steps in a timeline diagram shows different interleavings, and that tracing the ordering for two slow clicks gives the right result.
- Fast-click timeline interleaving. Explain that two fast clicks can produce a wrong result because actions from their click-handler timelines may interleave in an order the code does not control.
- Shared resources across timelines. Explain why two interleaved timelines can interfere with each other when they use the same global variables, and identify total, cart, and the DOM as shared resources in this example.
- Localizing the shared total. Explain why total can be changed from a global variable to a local one and what that changes about the timeline.
- Global input as argument. Explain how replacing reads of the cart global with an argument removes an implicit input and reduces sharing between timelines.
- Ordered global cart access. Explain why the remaining first steps that use the cart global cannot interfere with each other.
- Reusable asynchronous cart total. Explain why calc_cart_total() cannot return the total directly and how extracting a callback lets callers use the completed total for either DOM updates or accounting calculations.
- Asynchronous Results and Returns. Explain why returning from an asynchronous function does not return a result calculated by its callback, even though the function can technically have a return statement.
- Final Callback as Explicit Output. Describe how to extract an action from an asynchronous function by passing the action as a callback to receive the result, rather than returning a value as in the synchronous case.
- Timeline diagrams for finding bugs. Explain that drawing and reading timeline diagrams can reveal bugs.
- Reduced sharing between timelines. State that the chapter applied the principle of reducing shared resources to eliminate a bug.
- Shared DOM coordination need. Explain why two add-to-cart timelines must coordinate their writes to the DOM: both can write different values, but the DOM is needed to show the user their total.
What it builds on
- Timelines visualize distributed systems (chapter 2) · Introduces timelines as a way to visualize distributed systems.
- Actions, calculations, and data (chapter 3) · The distinction between actions and calculations.
- Principle: Minimize implicit inputs and outputs (chapter 5) · The principle of minimizing implicit inputs and outputs.
- Refactoring: Replace body with callback (chapter 10) · The replace-body-with-callback refactoring.
- Extracting a calculation from an action (chapter 4) · Extracting a calculation from an action establishes the earlier synchronous pattern of separating an action from value-producing code.
Section by section
Introduction
The introduction presents timeline diagrams as a way to see actions over time and reason about bugs, especially in distributed systems.
- Purpose of timeline diagrams: Explain that timeline diagrams represent sequences of actions over time, helping developers understand how software runs and diagnose or predict bugs, particularly in distributed systems.
Why it matters: Seeing when actions happen can make bugs easier to understand and anticipate.
Key terms: timeline diagrams, sequences of actions over time, distributed system
15.1 There’s a bug!
The section introduces a shopping-cart total bug that appears when customers click quickly but not during a slow clickthrough.
- Click-speed-dependent cart bug: Describe the reported mismatch between the shopping cart total and the checkout charge, and explain why a slow clickthrough does not reproduce the problem.
Why it matters: The difference between slow and quick clicks is the clue that guides the debugging.
Key terms: shopping cart, slow clickthrough
15.2 Now we can try to click twice fast
This section reproduces an add-to-cart bug caused by two quick clicks and explains why the code and use case diagram do not reveal what happens when operations overlap.
- Fast-click bug behavior: Describe how clicking the buy button twice quickly reproduces the bug: repeated attempts to add shoes twice produce different totals, and only $14 is correct.
Why it matters: The inconsistent totals establish the behavior the timeline analysis needs to explain. - Limits of sequential views: Explain why reading the code and use case diagram does not account for the fast-click bug: they look correct, and the system behaves correctly when clicks are spaced out, but they do not show what happens when two operations run at the same time.
Why it matters: It explains why examining the order of overlapping operations is necessary to investigate this bug.
Key terms: buy button, add shoes twice fast, use case diagram, running at the same time
15.3 The timeline diagram shows what happens over time
This section introduces timeline diagrams as a way to see how actions from quick successive clicks can interact over time.
- Timelines and their diagrams: Explain that a timeline is a sequence of actions over time and that a timeline diagram shows that sequence graphically. Describe how placing timelines side by side can reveal actions that interact or interfere.
Why it matters: Seeing actions side by side helps explain why two quick clicks might produce an incorrect result.
Key terms: timeline, timeline diagram, actions
15.4 The two fundamentals of timeline diagrams
This section gives two rules for drawing timeline diagrams: place sequential actions together and potentially concurrent or out-of-order actions apart.
- Sequential actions in one timeline: Explain that actions known to occur in order go one after another in the same timeline, while calculations can be omitted because their results do not depend on when they run.
Why it matters: This rule lets you show the order that matters without cluttering the diagram with calculations. - Uncertain actions in separate timelines: Explain that actions that can happen at the same time or in either order belong in separate, side-by-side timelines; asynchronous callbacks are one way this situation arises.
Why it matters: Separate timelines make an uncertain ordering visible instead of implying an order the code does not guarantee.
Key terms: actions, calculations, timeline, in sequence, parallel, separate timelines, asynchronous callbacks, out of order
15.5 Two tricky details about the order of actions
The section explains two JavaScript execution-order details that affect which actions appear in a timeline diagram and where they appear.
- Increment and assignment actions: Explain why total++ and total+=3 each produce two actions in a timeline diagram when total is global, even though each expression is short.
Why it matters: A compact expression can hide multiple actions that the timeline needs to show. - Argument evaluation order: Describe the order of actions when a function call uses an expression as an argument, such as logging a global variable.
Why it matters: Putting argument evaluation in the wrong place would give the diagram the wrong action order.
Key terms: ++, +=, actions, calculation, global variable, arguments, function, order of execution, timeline diagram
15.6 Drawing the add-to-cart timeline: Step 1
This section begins the add-to-cart timeline diagram by identifying actions in the code while setting calculations aside.
- Add-to-cart action identification: Describe the first step in drawing the add-to-cart timeline: mark the actions in the code and ignore calculations. Note that the code also contains callbacks passed to cost_ajax() and shipping_ajax(), without explaining how to draw them.
Why it matters: Separating actions from calculations gives you the starting point for drawing the timeline.
Key terms: actions, calculations, asynchronous callbacks, timeline diagram
15.7 Asynchronous calls require new timelines
The section introduces a timeline diagram for asynchronous code, where callbacks can run in a different order from the order in which the code is written.
- Asynchronous callback timelines: Explain that asynchronous callbacks happen in a new timeline, so the order in which lines execute can differ from the order in which they are written.
Why it matters: This is why a timeline diagram can reveal behavior that the code’s written order does not make obvious. - Action identification in diagrams: Describe the section’s first diagramming step: identify the actions, while treating reads of the assumed-local user and document variables as non-actions.
Why it matters: Identifying which operations are actions determines what goes into the timeline diagram.
Key terms: asynchronous callbacks, timeline, actions, local vars
15.8 Different languages, different threading models
The section compares four threading models by showing how each creates timelines and constrains their ordering and shared resources.
- Synchronous Single Thread Timeline: Explain why a single-threaded, synchronous program normally has one timeline and is easy to reason about, including what happens during input/output.
Why it matters: This model provides a simple contrast for the timelines created by asynchronous work and multiple threads. - Asynchronous Callback Timelines: Explain why an asynchronous input/output callback creates a new timeline in JavaScript.
Why it matters: A single thread does not imply a single timeline when callbacks can run at uncertain times. - Multithreaded Ordering And Locks: Describe how new threads create timelines, why their actions are difficult to order, and what locks control.
Why it matters: This explains why parallel threads create many possible orderings and why protected code needs coordination. - Message Passing Process Isolation: Explain how message-passing processes form separate timelines and why their lack of shared memory reduces ordering concerns.
Why it matters: It shows that timelines can interleave without the same shared-resource problems as threads that share memory.
Key terms: single-threaded, synchronous, blocks, timeline, single-threaded, asynchronous, callback, input/output, multi-threaded, interleaving, locks, message-passing processes
15.9 Building the timeline step-by-step
This section builds a timeline diagram line by line, placing ordinary actions and asynchronous callbacks on separate timelines.
- Placing actions on timelines: Trace how the section places actions from the JavaScript code onto a timeline diagram: code outside callbacks stays on the original timeline, while asynchronous callbacks get new timelines.
Why it matters: Putting actions on the right timelines makes the diagram reflect when the code can run. - Callback ordering and uncertainty: Explain what the dotted line says about the request and its callback, and why the callback's start time remains uncertain.
Why it matters: The diagram preserves the ordering the code guarantees without pretending the network has a predictable response time.
Key terms: original timeline, asynchronous callback, new timeline, actions, dotted line, callback, ajax function
15.10 Drawing the add-to-cart timeline: Step 2
Step 2 of drawing the add-to-cart timeline places every identified action on a diagram in order and gives each asynchronous callback a new timeline.
- Drawing the add-to-cart timeline: Describe how to draw the identified add-to-cart actions on a timeline diagram: place them in order and start a new timeline for each asynchronous callback.
Why it matters: This gives you a diagram that includes every action and represents the asynchronous callbacks separately.
Key terms: actions, timeline, ajax callbacks, asynchronous callbacks
15.11 Timeline diagrams capture the two kinds of sequential code
Explains how timeline diagrams distinguish sequential actions that may be interleaved from actions that cannot be interleaved.
- Interleavable and uninterrupted actions: Explain the two kinds of sequential code shown in a timeline diagram: actions that may have another timeline's action run between them, and actions that cannot. Describe how separate boxes connected by a line differ from multiple actions in one box.
Why it matters: The boxes show whether another action could run between two steps, even when those steps appear in sequence.
Key terms: interleave, timeline diagram, actions, box
15.12 Timeline diagrams capture the uncertain ordering of parallel code
The section explains how side-by-side timeline diagrams represent uncertain ordering between parallel actions.
- Parallel timeline orderings: Explain that side-by-side timelines represent parallel code, not a guarantee that their actions happen at the same time. Describe the three possible orderings of two actions and why a reader must consider them even when diagrams align the actions differently.
Why it matters: Considering every possible ordering helps you spot one that could cause a problem. - Range of possible orderings: Describe how adding actions or timelines quickly increases the number of possible orderings, and state that the platform’s threading model affects which orderings are possible.
Why it matters: A larger diagram may have many cases to consider, but the platform determines which are possible.
Key terms: parallel code, timelines, possible orderings, threading model
15.13 Principles of working with timelines
The section explains how reducing timelines, shortening them, and limiting shared resources make possible action orderings easier to reason about.
- Number of timelines: Explain why fewer timelines make a system easier to understand, even though threads, asynchronous callbacks, and client-server communication often require multiple timelines.
Why it matters: Fewer timelines mean fewer action orderings to account for. - Length of each timeline: Explain how eliminating steps from timelines reduces the number of possible orderings.
Why it matters: Shortening a timeline offers another way to reduce the orderings you must account for. - Shared resources across timelines: Distinguish reducing shared resources from reducing possible orderings: explain why steps on different timelines need less ordering analysis when they do not share resources.
Why it matters: You can focus ordering analysis on interactions that might affect one another. - Coordination of remaining sharing: Explain why resources that must remain shared require coordination between timelines.
Why it matters: Reducing sharing is not enough when some resources must still be shared.
Key terms: timelines, possible orderings, shorter timelines, steps, shared resources, coordinate
15.14 JavaScript’s single-thread
Explains why JavaScript’s single main thread prevents synchronous actions from interleaving, while asynchronous calls still create timeline uncertainty.
- Synchronous actions on one thread: Explain why synchronous JavaScript actions do not need separate timeline boxes for possible interleavings, contrasting this with two Java threads updating a shared variable.
Why it matters: This lets you focus timeline analysis on places where ordering really can vary. - Asynchronous timing uncertainty: Explain why asynchronous calls make timeline ordering a concern again in JavaScript, despite its single main thread.
Why it matters: A single thread removes simultaneous synchronous execution, not uncertainty about when later work will run.
Key terms: one main thread, synchronous actions, interleaving, asynchronous calls, runtime, synchronous or asynchronous operations
15.15 JavaScript’s asynchronous queue
This section explains how the browser’s single-threaded event loop processes jobs added to JavaScript’s job queue by events.
- Sequential job processing: Explain how the event loop processes the job queue: it takes one job, runs it to completion, and then takes the next, so two jobs do not run at the same time.
Why it matters: This explains why queued callbacks run sequentially even when events arrive unpredictably. - Event jobs and callbacks: Describe what causes a job to be added to the queue and what the job contains. Explain how the event loop uses its callback and event data.
Why it matters: It connects unpredictable browser events to the functions JavaScript eventually runs.
Key terms: job queue, event loop, single thread, job, event data, callback, events
15.16 AJAX and the event queue
This section explains how browser AJAX requests continue asynchronously and deliver responses through event callbacks.
- AJAX requests and naming: Describe AJAX as browser-based web requests and explain that this book marks functions making them with an _ajax suffix to signal that they are asynchronous.
Why it matters: The suffix helps you recognize an asynchronous request when reading the book’s code. - Asynchronous request ordering: Trace what happens after JavaScript initiates an AJAX request: it is queued for the networking engine, the code continues without waiting, and responses can arrive out of order, adding callbacks to the job queue out of order.
Why it matters: Request order alone cannot tell you the order in which response callbacks will be queued. - Response event callbacks: Explain how code receives an AJAX response by registering event callbacks, including what the load and error events indicate.
Why it matters: Event callbacks give your code a way to act when a request finishes without waiting for it.
Key terms: AJAX, _ajax suffix, AJAX request, networking engine, job queue, asynchronous, callback, load, error, event
15.17 A complete asynchronous example
Traces how a buy-button click moves through JavaScript’s event queue and an asynchronous AJAX request before the cart display is updated.
- Buy Button Asynchronous Timeline: Trace the buy button’s sequence from registering a click callback through the queued click job, AJAX request, and later completion callback. Describe what each callback changes on the page.
Why it matters: Separating the two callbacks makes it easier to see when each visible change happens.
Key terms: callback, event loop, queue, AJAX request, networking engine
15.18 Simplifying the timeline
The section shows how JavaScript’s single-threaded runtime lets you simplify a completed timeline diagram.
- Single Timeline Action Consolidation: Explain why actions on one JavaScript timeline can be consolidated and how that changes the diagram.
Why it matters: This removes impossible orderings from a JavaScript timeline diagram. - Conditional Timeline Consolidation: State when the second JavaScript simplification applies and why it does not apply to the diagram discussed here.
Why it matters: The condition prevents you from merging timelines that must remain separate in the diagram.
Key terms: single thread, consolidate all actions on a single timeline, dotted lines, consolidate timelines, one new timeline
15.19 Reading our finished timeline
Shows how to read a finished timeline diagram to distinguish guaranteed from uncertain action orderings and check whether the code behaves correctly in every case.
- Certain and uncertain orderings: Explain which actions in the finished diagram have a guaranteed order and which may vary. Describe how JavaScript’s single thread limits the possible orderings of the two AJAX callbacks.
Why it matters: Separating guaranteed order from variable order helps you identify which outcomes the code must handle. - Correctness across possible orderings: Explain how possible action orderings can be used to judge whether code has a timing bug, and apply that test to the loading spinner in this section.
Why it matters: Checking every possible ordering exposes timing bugs that one successful run might miss.
Key terms: timeline diagrams, main timeline, callback timelines, certain, uncertain orderings, possible orderings, loading spinner, timing issues, bug
15.20 Simplifying the add-to-cart timeline diagram: Step 3
The section simplifies the add-to-cart timeline diagram using two ordered JavaScript-specific consolidations while preserving possible interleaving.
- Ordered JavaScript timeline simplifications: Describe the two simplifications in order: combine actions on each timeline into one box, then combine timelines that end by starting one new timeline. Explain why JavaScript’s single thread permits the first simplification and how AJAX callbacks permit the second.
Why it matters: These steps make a callback-heavy timeline easier to draw and read without losing the relevant ordering. - Preserved interleaving in boxes: Explain why the resulting single timeline must still show separate boxes rather than merging every action into one box.
Why it matters: Keeping the boxes separate prevents the simpler diagram from hiding possible interleaving.
Key terms: consolidate actions, consolidate timelines, single thread, ajax call, callback, separate boxes, possible interleaving, timeline
15.21 Review: Drawing the timeline (steps 1–3)
Reviews how to draw and simplify an add-to-cart timeline diagram while preserving the timing uncertainty caused by asynchronous actions.
- Three diagramming steps: Describe the three steps used to make the timeline diagram: identify actions, draw them according to whether they are sequential or parallel, and simplify the result.
Why it matters: These steps give you a repeatable way to turn code into a timeline diagram. - JavaScript timeline simplification: Explain how JavaScript’s single-threaded model and asynchronous callbacks let the example’s diagram be consolidated, and why separate boxes are still needed.
Why it matters: A simpler diagram is useful only if it still shows where timing can vary.
Key terms: actions, sequential, parallel, timeline, simplify, single-threaded model, asynchronous action, callbacks, consolidate actions, consolidate timelines
15.22 Summary: Drawing timeline diagrams
This section summarizes how to identify actions, draw and simplify timeline diagrams, and evaluate possible action orderings.
- Atomic actions on timelines: Describe how to identify the actions for a timeline diagram by breaking composite actions down to atomic reads and writes, including operations such as ++ and +=.
Why it matters: Missing a read or write can hide an ordering problem. - Sequential and parallel timelines: Explain how to place actions on the same or separate timelines based on whether their execution is ordered or can occur in parallel, and how dotted lines show constraints between them.
Why it matters: The placement and dotted lines make possible and impossible orderings visible. - Timeline simplification and reading: Describe the section’s guidelines for simplifying a timeline diagram and evaluating the possible orders of actions on different timelines.
Why it matters: A simpler diagram helps you spot which possible orderings could cause trouble.
Key terms: actions, composite actions, atomic actions, sequence, parallel, timelines, dotted lines, constrained order, simplify the timeline, interleaved
15.23 Timeline diagrams side-by-side can reveal problems
Placing a timeline for each button click side by side reveals possible interleavings that a single-click diagram cannot show.
- Two-click timeline comparison: Explain why the cart-update timeline must be shown twice to examine rapid clicks, and describe the ordering constraint shown between the two clicks.
Why it matters: This view exposes possible interactions between clicks that are invisible when examining one click alone.
Key terms: timeline, interleave, event queue, dotted line
15.24 Two slow clicks get the right result
The section uses a timeline diagram to show that one ordering of two slow clicks produces the right result.
- Slow-click timeline ordering: Explain that stretching the lines between steps in a timeline diagram shows different interleavings, and that tracing the ordering for two slow clicks gives the right result.
Why it matters: Tracing a particular ordering lets you check what result that sequence of events produces.
Key terms: timeline diagram, interleavings, two slow clicks
15.25 Two fast clicks can get the wrong result
The section shows that fast clicks can produce a wrong result when their timelines interleave, and explains why checking every possible ordering is impractical.
- Fast-click timeline interleaving: Explain that two fast clicks can produce a wrong result because actions from their click-handler timelines may interleave in an order the code does not control.
Why it matters: A result that looks correct with slow clicks may still fail when clicks happen close together. - Limits of ordering enumeration: Explain why tracing every possible ordering is not a practical way to guarantee correct code as timelines grow.
Why it matters: The number of possible interleavings explains why finding one failing trace is not enough to ensure correctness.
Key terms: click handler timelines, interleaving, possible orderings, timelines
15.26 Timelines that share resources can cause problems
The section identifies shared resources as the cause of problems when add-to-cart timelines interleave.
- Shared resources across timelines: Explain why two interleaved timelines can interfere with each other when they use the same global variables, and identify total, cart, and the DOM as shared resources in this example.
Why it matters: Spotting shared resources helps explain why fast clicks can produce the wrong result.
Key terms: timelines, sharing resources, global variables, total, cart, DOM
15.27 Converting a global variable to a local one
This section replaces a shared global total with a local variable to make more timeline orderings produce the correct result.
- Localizing the shared total: Explain why total can be changed from a global variable to a local one and what that changes about the timeline.
Why it matters: Removing unnecessary shared state can prevent wrong results without reducing the number of possible orderings.
Key terms: global variable, local variable, total, timeline, possible orderings
15.28 Converting a global variable to an argument
The section replaces a shared cart global with an argument, explains why the remaining ordered access is safe, and identifies what still makes the function an action.
- Global input as argument: Explain how replacing reads of the cart global with an argument removes an implicit input and reduces sharing between timelines.
Why it matters: Explicit inputs make it easier to see what a timeline depends on. - Ordered global cart access: Explain why the remaining first steps that use the cart global cannot interfere with each other.
Why it matters: Multiple timelines do not make every use of shared mutable state unsafe; the ordering of its accesses matters. - Remaining actions and DOM sharing: Distinguish removing global-variable access from turning calc_cart_total() into a calculation, and describe the shared resource that remains.
Why it matters: Removing one shared dependency improves the function without resolving every timing problem.
Key terms: implicit input, cart global variable, argument, timelines, second timeline, dotted line, global mutable state, cart, calc_cart_total(), calculation
15.29 Making our code more reusable
This section makes the asynchronously calculated cart total reusable by passing it to a callback instead of updating the DOM directly.
- Reusable asynchronous cart total: Explain why calc_cart_total() cannot return the total directly and how extracting a callback lets callers use the completed total for either DOM updates or accounting calculations.
Why it matters: Callers can use the calculated number without being forced to modify the DOM.
Key terms: calc_cart_total(), implicit output, callback, update_total_dom(), replace body with callback
15.30 Principle: In an asynchronous context, we use a final callback instead of a return value as our explicit output
Explains why asynchronous results cannot be returned to a caller in the usual way and how a final callback provides an explicit output while keeping actions outside the function.
- Asynchronous Results and Returns: Explain why returning from an asynchronous function does not return a result calculated by its callback, even though the function can technically have a return statement.
Why it matters: It explains why a seemingly reasonable return statement can produce a value before the result you wanted exists. - Final Callback as Explicit Output: Describe how to extract an action from an asynchronous function by passing the action as a callback to receive the result, rather than returning a value as in the synchronous case.
Why it matters: A callback gives later results an explicit path to the action that uses them.
Key terms: asynchronous calls, callback, return, event loop, final callback, explicit output, extract actions, synchronous functions, asynchronous functions
15.31 Conclusion
The conclusion recaps how timeline diagrams, JavaScript threading knowledge, and reduced resource sharing helped find and eliminate a bug.
- Timeline diagrams for finding bugs: Explain that drawing and reading timeline diagrams can reveal bugs.
Why it matters: A timeline diagram gives you a way to look for bugs in how events unfold. - JavaScript informed timeline simplification: Explain that knowledge of the JavaScript threading model helped simplify the diagrams, making timelines shorter and reducing their number.
Why it matters: The threading model helps keep a timeline diagram manageable. - Reduced sharing between timelines: State that the chapter applied the principle of reducing shared resources to eliminate a bug.
Why it matters: Reducing what timelines share can remove a source of bugs.
Key terms: timeline diagrams, JavaScript threading model, timelines, reducing shared resources
15.32 Summary
15.33 Up next…
The section explains why the DOM remains a shared resource that two add-to-cart timelines must coordinate to use safely.
- Shared DOM coordination need: Explain why two add-to-cart timelines must coordinate their writes to the DOM: both can write different values, but the DOM is needed to show the user their total.
Why it matters: It identifies the remaining shared resource that the next chapter needs to handle.
Key terms: shared resource, DOM, add-to-cart timelines, coordinating
Where this is used later
- How the code was changed (chapter 17) · Introduces uncertain ordering when code runs in parallel.
- Summary: Manipulating timelines (chapter 17) · The principles of working with timelines.
- We need to guarantee the order of the DOM updates (chapter 16) · The need to guarantee the order of updates applies the principle that shared resources require safe coordination.
- Identify actions: Step 1 (chapter 17) · Earlier simplification of timeline diagrams when details can safely be omitted.
- Principle: Analyze the timeline diagram to know if there will be problems (chapter 16) · Timeline analysis is used to determine whether shared actions can cause problems.
- Draw each action: Step 2 (chapter 17) · Drawing each action relies on representing ordered and parallel execution.
- Analyzing the timeline (chapter 16) · Analyzing a later timeline depends on examining its possible action orderings.
- Building a queue in JavaScript (chapter 16) · Moving a global variable into local scope limits its reach.
Concepts explained in this chapter
- actionAn action is a computation whose observable result depends on when or how it is performed and may involve effects beyond producing a value.
- interleavingAn ordering formed by combining steps from multiple timelines while preserving the order of steps within each timeline.
- single-threaded execution modelA single-threaded runtime is an execution environment in which program actions execute on one thread at a time.
- threading modelA specification of how program execution is divided among threads and how those threads can run concurrently.
- JavaScriptA high-level programming language commonly used for scripting and application development across web and server environments.
- event loopA runtime mechanism that repeatedly retrieves queued events or callbacks and invokes them when the call stack is available.
- global variableA variable whose binding is accessible across broad program or module scope rather than being confined to a single function or block.
- queueA book-specific JavaScript function that creates an encapsulated queue and returns an operation for submitting work to it.
- return valueThe value produced as the result of a function invocation.
- implicit inputAn input obtained by a computation from surrounding state or context rather than supplied explicitly as a function argument.
- mathematical calculationA calculation is a category of code that deterministically computes a result from its inputs without directly interacting with the outside world.
- sequential processingA sequential action is an action that is ordered to occur in sequence with other actions on the same execution timeline.
- parallelismExecution in which multiple actions may occur simultaneously or without a fixed order relative to one another.
- scopeThe region of a program in which a binding can be accessed or referenced.
- DOM updateA modification to the Document Object Model that changes a document's represented content, structure, or presentation.
- implicit outputAn effect of a function that changes external state or performs an observable operation rather than returning the result directly.
- replace body with callbackA refactoring technique that extracts unchanged before-and-after code into a function and supplies the varying body as a callback argument.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
