Async Workflows and Source Panels
Promise Callback Panel
Trace named Promise callbacks as ordered single-thread replay steps.
promise callback
Named callbacks make each Promise step visible in replay while keeping the sequence deterministic.
Promise Callback Panel
promise_callback.ts
Replay: real traced execution (multi-file project)
type StepResult = {
label: string;
value: number;
};
const base: number = 6;
let first: StepResult = { label: "pending", value: 0 };
let second: StepResult = { label: "pending", value: 0 };
function addStep(value: number): StepResult {
first = { label: "add", value: value + 4 };
return first;
}
function finishStep(result: StepResult): void {
second = { label: "double", value: result.value * 2 };
console.log(`base=${base}`);
console.log(`${first.label}=${first.value}`);
console.log(`${second.label}=${second.value}`);
}
Promise.resolve(base)
.then(addStep)
.then(finishStep);
type StepResult = {
label: string;
value: number;
};
const base: number = 3;
let first: StepResult = { label: "pending", value: 0 };
let second: StepResult = { label: "pending", value: 0 };
function addStep(value: number): StepResult {
first = { label: "add", value: value + 4 };
return first;
}
function finishStep(result: StepResult): void {
second = { label: "double", value: result.value * 2 };
console.log(`base=${base}`);
console.log(`${first.label}=${first.value}`);
console.log(`${second.label}=${second.value}`);
}
Promise.resolve(base)
.then(addStep)
.then(finishStep);
type StepResult = {
label: string;
value: number;
};
const base: number = 9;
let first: StepResult = { label: "pending", value: 0 };
let second: StepResult = { label: "pending", value: 0 };
function addStep(value: number): StepResult {
first = { label: "add", value: value + 4 };
return first;
}
function finishStep(result: StepResult): void {
second = { label: "double", value: result.value * 2 };
console.log(`base=${base}`);
console.log(`${first.label}=${first.value}`);
console.log(`${second.label}=${second.value}`);
}
Promise.resolve(base)
.then(addStep)
.then(finishStep);
base ← 6, first ← [object Object], second ← [object Object]
3 value: number;4};56const base→ 6: number = 6; //@base=3, 97let first→ [object Object]: StepResult = { label: "pending", value: 0 };8let second→ [object Object]: StepResult = { label: "pending", value: 0 };910function addStep(value: number): StepResult {11 first = { label: "add", value: value + 4 };12 return first;13}1415function finishStep(result: StepResult): void {16 second = { label: "double", value: result.value * 2 };17 console.log(`base=${base}`);18 console.log(`${first.label}=${first.value}`);19 console.log(`${second.label}=${second.value}`);20}2122Promise.resolve(base6)23 .then(addStepfunction addStep(value) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|" + ("10.18-10.23:value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|@@END"); first = { label: "add", value: value + 4 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|" + ("10.46-11.10:\n first:" + String(first).length + ":" + String(first) + ", " + "11.35-11.41: value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|11.48-12.18:\n return first;|" + ("12.11-12.17: first:" + String(first).length + ":" + String(first)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|LEAVE|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|@@END"); return first; })24 .then(finishStepfunction finishStep(result) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|13.2-15.48-20.2:\n\nfunction finishStep(result: StepResult): void {|" + ("15.21-15.27:result:" + String(result).length + ":" + String(result)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|@@END"); second = { label: "double", value: result.value * 2 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|" + ("15.48-16.11:\n second:" + String(second).length + ":" + String(second) + ", " + "16.39-16.52: result.value:" + String(result.value).length + ":" + String(result.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); { const __stdout = String(`base=${base}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|16.59-17.33:\n console.log(`base=${base}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); { const __stdout = String(`${first.label}=${first.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); { const __stdout = String(`${second.label}=${second.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); });first ← [object Object], value ← 6
7let first: StepResult = { label: "pending", value: 0 };8let second: StepResult = { label: "pending", value: 0 };910function addStep(value6: number): StepResult {11 first = { label: "add", value: value→ 6 + 4 };12 return first[object Object];13}second ← [object Object], result.value ← 10
12 return first;13}1415function finishStep(result[object Object]: StepResult): void {16 second = { label: "double", value: result.value→ 10 * 2 };17 console.log(`base=${base6}`);18 console.log(`${first.labeladd}=${first.value10}`);19 console.log(`${second.labeldouble}=${second.value20}`);20}outputbase=6 add=10 double=20values this step[object Object]second
base ← 3, first ← [object Object], second ← [object Object]
3 value: number;4};56const base→ 3: number = 3;7let first→ [object Object]: StepResult = { label: "pending", value: 0 };8let second→ [object Object]: StepResult = { label: "pending", value: 0 };910function addStep(value: number): StepResult {11 first = { label: "add", value: value + 4 };12 return first;13}1415function finishStep(result: StepResult): void {16 second = { label: "double", value: result.value * 2 };17 console.log(`base=${base}`);18 console.log(`${first.label}=${first.value}`);19 console.log(`${second.label}=${second.value}`);20}2122Promise.resolve(base3)23 .then(addStepfunction addStep(value) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|" + ("10.18-10.23:value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|@@END"); first = { label: "add", value: value + 4 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|" + ("10.46-11.10:\n first:" + String(first).length + ":" + String(first) + ", " + "11.35-11.41: value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|11.48-12.18:\n return first;|" + ("12.11-12.17: first:" + String(first).length + ":" + String(first)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|LEAVE|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|@@END"); return first; })24 .then(finishStepfunction finishStep(result) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|13.2-15.48-20.2:\n\nfunction finishStep(result: StepResult): void {|" + ("15.21-15.27:result:" + String(result).length + ":" + String(result)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|@@END"); second = { label: "double", value: result.value * 2 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|" + ("15.48-16.11:\n second:" + String(second).length + ":" + String(second) + ", " + "16.39-16.52: result.value:" + String(result.value).length + ":" + String(result.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); { const __stdout = String(`base=${base}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|16.59-17.33:\n console.log(`base=${base}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); { const __stdout = String(`${first.label}=${first.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); { const __stdout = String(`${second.label}=${second.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); });first ← [object Object], value ← 3
7let first: StepResult = { label: "pending", value: 0 };8let second: StepResult = { label: "pending", value: 0 };910function addStep(value3: number): StepResult {11 first = { label: "add", value: value→ 3 + 4 };12 return first[object Object];13}second ← [object Object], result.value ← 7
12 return first;13}1415function finishStep(result[object Object]: StepResult): void {16 second = { label: "double", value: result.value→ 7 * 2 };17 console.log(`base=${base3}`);18 console.log(`${first.labeladd}=${first.value7}`);19 console.log(`${second.labeldouble}=${second.value14}`);20}outputbase=3 add=7 double=14values this step[object Object]second
base ← 9, first ← [object Object], second ← [object Object]
3 value: number;4};56const base→ 9: number = 9;7let first→ [object Object]: StepResult = { label: "pending", value: 0 };8let second→ [object Object]: StepResult = { label: "pending", value: 0 };910function addStep(value: number): StepResult {11 first = { label: "add", value: value + 4 };12 return first;13}1415function finishStep(result: StepResult): void {16 second = { label: "double", value: result.value * 2 };17 console.log(`base=${base}`);18 console.log(`${first.label}=${first.value}`);19 console.log(`${second.label}=${second.value}`);20}2122Promise.resolve(base9)23 .then(addStepfunction addStep(value) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|" + ("10.18-10.23:value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|@@END"); first = { label: "add", value: value + 4 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|10.46-11.48:\n first = { label: \"add\", value: value + 4 };|" + ("10.46-11.10:\n first:" + String(first).length + ":" + String(first) + ", " + "11.35-11.41: value:" + String(value).length + ":" + String(value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|11.48-12.18:\n return first;|" + ("12.11-12.17: first:" + String(first).length + ":" + String(first)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|LEAVE|8.57-10.46-13.2:\n\nfunction addStep(value: number): StepResult {|@@END"); return first; })24 .then(finishStepfunction finishStep(result) { console.log("@@TRACE|promise_callback.ts|-1|ENTER|13.2-15.48-20.2:\n\nfunction finishStep(result: StepResult): void {|" + ("15.21-15.27:result:" + String(result).length + ":" + String(result)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|@@END"); second = { label: "double", value: result.value * 2 }; console.log("@@TRACE|promise_callback.ts|-1|AFTER|15.48-16.59:\n second = { label: \"double\", value: result.value * 2 };|" + ("15.48-16.11:\n second:" + String(second).length + ":" + String(second) + ", " + "16.39-16.52: result.value:" + String(result.value).length + ":" + String(result.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); { const __stdout = String(`base=${base}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|16.59-17.33:\n console.log(`base=${base}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|16.59-17.33:\n console.log(`base=${base}`);|" + ("17.25-17.29:base:" + String(base).length + ":" + String(base)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); { const __stdout = String(`${first.label}=${first.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|17.33-18.50:\n console.log(`${first.label}=${first.value}`);|" + ("18.20-18.31:first.label:" + String(first.label).length + ":" + String(first.label) + ", " + "18.35-18.46:first.value:" + String(first.value).length + ":" + String(first.value)) + "@@END"); console.log("@@TRACE|promise_callback.ts|-1|BEFORE|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); { const __stdout = String(`${second.label}=${second.value}`); console.log("@@TRACE|promise_callback.ts|-1|STDOUT|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + __stdout.length + ":" + __stdout + "@@END"); } ; console.log("@@TRACE|promise_callback.ts|-1|AFTER|18.50-19.52:\n console.log(`${second.label}=${second.value}`);|" + ("19.20-19.32:second.label:" + String(second.label).length + ":" + String(second.label) + ", " + "19.36-19.48:second.value:" + String(second.value).length + ":" + String(second.value)) + "@@END"); });first ← [object Object], value ← 9
7let first: StepResult = { label: "pending", value: 0 };8let second: StepResult = { label: "pending", value: 0 };910function addStep(value9: number): StepResult {11 first = { label: "add", value: value→ 9 + 4 };12 return first[object Object];13}second ← [object Object], result.value ← 13
12 return first;13}1415function finishStep(result[object Object]: StepResult): void {16 second = { label: "double", value: result.value→ 13 * 2 };17 console.log(`base=${base9}`);18 console.log(`${first.labeladd}=${first.value13}`);19 console.log(`${second.labeldouble}=${second.value26}`);20}outputbase=9 add=13 double=26values this step[object Object]second