Script Valley
Reading Other People's Code
Reading Code You Didn't WriteLesson 2.2

How to trace data flow through a function call chain

call stack tracing, argument passing, return value propagation, intermediate variables, function composition, callback chains, async/await tracing

Follow the Data, Not the Code

Function call chain data flow diagram

When reading a chain of function calls, ignore the implementation details of each function initially. Track what data goes in, what comes out, and how it transforms at each step.

Tracing Step by Step

// Trace what happens to 'userId' through this chain
const dashboard = await buildDashboard(userId);

// Step 1: buildDashboard receives userId (string)
async function buildDashboard(userId: string) {
  const user = await getUser(userId);       // userId → User object
  const orders = await getOrders(user.id);  // user.id → Order[]
  const stats = computeStats(orders);       // Order[] → Stats object
  return formatDashboard(user, stats);      // (User, Stats) → HTML string
}

// Data lineage: userId → User → Order[] → Stats → HTML

Name Your Mental Variables

As you trace, write down (literally, on paper or in comments) what each variable holds at each step. Professional code readers annotate as they go — don't try to hold the entire call chain in your head.

// Annotation style while reading:
const result = transform(parse(fetch(url)));
//    string  <-- object <-- raw  <-- url
// Read right-to-left: url → fetch → raw string → parse → object → transform → result

When you hit an async boundary (await, .then), note that execution pauses there and something external (network, disk) produces the next value. That external source is important context for what can go wrong.

Up next

What naming conventions tell you about a codebase's intent

Sign in to track progress