When I debug a script that contains asynchronous functions and I want to have the statements grouped into a console group. The groups get mixed up and the whole debugging becomes confusing.
Is there any way to have the statements in the console better organized?
I prepared a simple example:
let C = class
{
color;
colorName;
constructor ( color )
{
this.color = `font-weight: strong; color: ${ color }`;
this.colorName = color;
this.run();
}
async run () {
console.groupCollapsed( '%c Class C ', this.color, this.colorName );
console.log( '%c run', this.color );
await this.asyncMethod();
this.syncMethod();
console.groupEnd();
}
async asyncMethod () {
return new Promise( ( resolve ) => {
setTimeout( () => {
console.log( '%c asyncMethod', this.color, this.colorName );
resolve();
}, 99 );
} );
}
syncMethod ()
{
console.group( '%c syncMethod', this.color, this.colorName );
this.subSyncMethod();
console.groupEnd();
}
subSyncMethod ()
{
console.log( '%c subSyncMethod', this.color, this.colorName );
}
}
new C( 'red' );
new C( 'green' );
And the result is unfortunately this:
I need sometning nice like:
I would need to somehow separate the individual statements, even in the case of 2 class calls immediately after each other. Some console.something() command which i dont know or some custom function to delay console writing or sometnihg like that. Or some post-sort in console? It's possible?
It is not possible to achieve what you want with any of the functions in the console object. Basically what you are asking for is stack tracing the async functions. So whenever you encounter a console.log
statement inside an async function, you need to stack trace and find the "immediately preceding" console.group
statement and append the console.log
message to it.
Stack tracing the async functions is not a simple operation. See this answer on how the v8 engine reconstructs async stacktraces.
But if your use case is simple you can achive this by writing your own wrapper class for the console object. Example is given below.
class konsole {
messages = [];
depth = 0;
group(...label) {
this.messages.push({
type: 'group',
value: label
});
this.depth += 1;
}
groupCollapsed(...label) {
this.messages.push({
type: 'groupCollapsed',
value: label
});
this.depth += 1;
}
log(...message) {
this.messages.push({
type: 'log',
value: message
});
}
groupEnd() {
this.depth -= 1;
this.messages.push({
type: 'groupEnd',
value: null
});
if (this.depth == 0) {
// Print in the console
this.messages.forEach((message) => {
if (message.type == 'group') {
console.group( ...message.value );
} else if (message.type == 'groupCollapsed') {
console.groupCollapsed( ...message.value );
} else if (message.type == 'log') {
console.log( ...message.value );
} else if (message.type == 'groupEnd') {
console.groupEnd();
}
})
}
}
}
let C = class
{
color;
colorName;
konsole;
constructor ( color )
{
this.color = `font-weight: strong; color: ${ color }`;
this.colorName = color;
this.konsole = new konsole();
this.run();
}
async run () {
this.konsole.groupCollapsed( '%c Class C ', this.color, this.colorName );
this.konsole.log( '%c run', this.color );
await this.asyncMethod();
this.syncMethod();
this.konsole.groupEnd();
}
async asyncMethod () {
return new Promise( ( resolve ) => {
setTimeout( () => {
this.konsole.log( '%c asyncMethod', this.color, this.colorName );
resolve();
}, 99 );
} );
}
syncMethod ()
{
this.konsole.group( '%c syncMethod', this.color, this.colorName );
this.subSyncMethod();
this.konsole.groupEnd();
}
subSyncMethod ()
{
this.konsole.log( '%c subSyncMethod', this.color, this.colorName );
}
}
new C( 'red' );
new C( 'green' );
Note: Stackoverflow snippet runner doesn't show the colors. Checkout this jsfiddle and open the console to see the colored output.
Result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With