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

base
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);
  1. 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");
    });
  2. 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}
  3. 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=20
    values this step[object Object]second
  1. 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");
    });
  2. 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}
  3. 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=14
    values this step[object Object]second
  1. 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");
    });
  2. 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}
  3. 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=26
    values this step[object Object]second