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
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 → HTMLName 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 → resultWhen 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.
