7
7
<!-- source_link=lib/async_hooks.js -->
8
8
9
9
<!-- YAML
10
- llm_description : >
10
+ llmDescription : >
11
11
Tracks asynchronous execution context. Enables storing and propagating state
12
12
across async operations like callbacks and promises. Useful for request
13
13
tracking, logging, or context management. Provides AsyncLocalStorage for
@@ -68,16 +68,18 @@ function logWithId(msg) {
68
68
}
69
69
70
70
let idSeq = 0 ;
71
- http .createServer ((req , res ) => {
72
- asyncLocalStorage .run (idSeq++ , () => {
73
- logWithId (' start' );
74
- // Imagine any chain of async operations here
75
- setImmediate (() => {
76
- logWithId (' finish' );
77
- res .end ();
71
+ http
72
+ .createServer ((req , res ) => {
73
+ asyncLocalStorage .run (idSeq++ , () => {
74
+ logWithId (' start' );
75
+ // Imagine any chain of async operations here
76
+ setImmediate (() => {
77
+ logWithId (' finish' );
78
+ res .end ();
79
+ });
78
80
});
79
- });
80
- }) .listen (8080 );
81
+ })
82
+ .listen (8080 );
81
83
82
84
http .get (' http://localhost:8080' );
83
85
http .get (' http://localhost:8080' );
@@ -100,16 +102,18 @@ function logWithId(msg) {
100
102
}
101
103
102
104
let idSeq = 0 ;
103
- http .createServer ((req , res ) => {
104
- asyncLocalStorage .run (idSeq++ , () => {
105
- logWithId (' start' );
106
- // Imagine any chain of async operations here
107
- setImmediate (() => {
108
- logWithId (' finish' );
109
- res .end ();
105
+ http
106
+ .createServer ((req , res ) => {
107
+ asyncLocalStorage .run (idSeq++ , () => {
108
+ logWithId (' start' );
109
+ // Imagine any chain of async operations here
110
+ setImmediate (() => {
111
+ logWithId (' finish' );
112
+ res .end ();
113
+ });
110
114
});
111
- });
112
- }) .listen (8080 );
115
+ })
116
+ .listen (8080 );
113
117
114
118
http .get (' http://localhost:8080' );
115
119
http .get (' http://localhost:8080' );
@@ -196,9 +200,13 @@ calls the function passed to it within the captured context.
196
200
197
201
``` js
198
202
const asyncLocalStorage = new AsyncLocalStorage ();
199
- const runInAsyncScope = asyncLocalStorage .run (123 , () => AsyncLocalStorage .snapshot ());
200
- const result = asyncLocalStorage .run (321 , () => runInAsyncScope (() => asyncLocalStorage .getStore ()));
201
- console .log (result); // returns 123
203
+ const runInAsyncScope = asyncLocalStorage .run (123 , () =>
204
+ AsyncLocalStorage .snapshot ()
205
+ );
206
+ const result = asyncLocalStorage .run (321 , () =>
207
+ runInAsyncScope (() => asyncLocalStorage .getStore ())
208
+ );
209
+ console .log (result); // returns 123
202
210
```
203
211
204
212
AsyncLocalStorage.snapshot() can replace the use of AsyncResource for simple
@@ -208,7 +216,9 @@ async context tracking purposes, for example:
208
216
class Foo {
209
217
#runInAsyncScope = AsyncLocalStorage .snapshot ();
210
218
211
- get () { return this .#runInAsyncScope (() => asyncLocalStorage .getStore ()); }
219
+ get () {
220
+ return this .#runInAsyncScope (() => asyncLocalStorage .getStore ());
221
+ }
212
222
}
213
223
214
224
const foo = asyncLocalStorage .run (123 , () => new Foo ());
@@ -451,9 +461,10 @@ import { AsyncResource, executionAsyncId } from 'node:async_hooks';
451
461
// AsyncResource() is meant to be extended. Instantiating a
452
462
// new AsyncResource() also triggers init. If triggerAsyncId is omitted then
453
463
// async_hook.executionAsyncId() is used.
454
- const asyncResource = new AsyncResource (
455
- type, { triggerAsyncId: executionAsyncId (), requireManualDestroy: false },
456
- );
464
+ const asyncResource = new AsyncResource (type, {
465
+ triggerAsyncId: executionAsyncId (),
466
+ requireManualDestroy: false ,
467
+ });
457
468
458
469
// Run a function in the execution context of the resource. This will
459
470
// * establish the context of the resource
@@ -479,9 +490,10 @@ const { AsyncResource, executionAsyncId } = require('node:async_hooks');
479
490
// AsyncResource() is meant to be extended. Instantiating a
480
491
// new AsyncResource() also triggers init. If triggerAsyncId is omitted then
481
492
// async_hook.executionAsyncId() is used.
482
- const asyncResource = new AsyncResource (
483
- type, { triggerAsyncId: executionAsyncId (), requireManualDestroy: false },
484
- );
493
+ const asyncResource = new AsyncResource (type, {
494
+ triggerAsyncId: executionAsyncId (),
495
+ requireManualDestroy: false ,
496
+ });
485
497
486
498
// Run a function in the execution context of the resource. This will
487
499
// * establish the context of the resource
@@ -672,7 +684,7 @@ class WorkerPoolTaskInfo extends AsyncResource {
672
684
673
685
done (err , result ) {
674
686
this .runInAsyncScope (this .callback , null , err, result);
675
- this .emitDestroy (); // `TaskInfo`s are used only once.
687
+ this .emitDestroy (); // `TaskInfo`s are used only once.
676
688
}
677
689
}
678
690
@@ -684,8 +696,7 @@ export default class WorkerPool extends EventEmitter {
684
696
this .freeWorkers = [];
685
697
this .tasks = [];
686
698
687
- for (let i = 0 ; i < numThreads; i++ )
688
- this .addNewWorker ();
699
+ for (let i = 0 ; i < numThreads; i++ ) this .addNewWorker ();
689
700
690
701
// Any time the kWorkerFreedEvent is emitted, dispatch
691
702
// the next task pending in the queue, if any.
@@ -711,10 +722,8 @@ export default class WorkerPool extends EventEmitter {
711
722
worker .on (' error' , (err ) => {
712
723
// In case of an uncaught exception: Call the callback that was passed to
713
724
// `runTask` with the error.
714
- if (worker[kTaskInfo])
715
- worker[kTaskInfo].done (err, null );
716
- else
717
- this .emit (' error' , err);
725
+ if (worker[kTaskInfo]) worker[kTaskInfo].done (err, null );
726
+ else this .emit (' error' , err);
718
727
// Remove the worker from the list and start a new Worker to replace the
719
728
// current one.
720
729
this .workers .splice (this .workers .indexOf (worker), 1 );
@@ -760,7 +769,7 @@ class WorkerPoolTaskInfo extends AsyncResource {
760
769
761
770
done (err , result ) {
762
771
this .runInAsyncScope (this .callback , null , err, result);
763
- this .emitDestroy (); // `TaskInfo`s are used only once.
772
+ this .emitDestroy (); // `TaskInfo`s are used only once.
764
773
}
765
774
}
766
775
@@ -772,8 +781,7 @@ class WorkerPool extends EventEmitter {
772
781
this .freeWorkers = [];
773
782
this .tasks = [];
774
783
775
- for (let i = 0 ; i < numThreads; i++ )
776
- this .addNewWorker ();
784
+ for (let i = 0 ; i < numThreads; i++ ) this .addNewWorker ();
777
785
778
786
// Any time the kWorkerFreedEvent is emitted, dispatch
779
787
// the next task pending in the queue, if any.
@@ -799,10 +807,8 @@ class WorkerPool extends EventEmitter {
799
807
worker .on (' error' , (err ) => {
800
808
// In case of an uncaught exception: Call the callback that was passed to
801
809
// `runTask` with the error.
802
- if (worker[kTaskInfo])
803
- worker[kTaskInfo].done (err, null );
804
- else
805
- this .emit (' error' , err);
810
+ if (worker[kTaskInfo]) worker[kTaskInfo].done (err, null );
811
+ else this .emit (' error' , err);
806
812
// Remove the worker from the list and start a new Worker to replace the
807
813
// current one.
808
814
this .workers .splice (this .workers .indexOf (worker), 1 );
@@ -851,8 +857,7 @@ let finished = 0;
851
857
for (let i = 0 ; i < 10 ; i++ ) {
852
858
pool .runTask ({ a: 42 , b: 100 }, (err , result ) => {
853
859
console .log (i, err, result);
854
- if (++ finished === 10 )
855
- pool .close ();
860
+ if (++ finished === 10 ) pool .close ();
856
861
});
857
862
}
858
863
` ` `
@@ -867,8 +872,7 @@ let finished = 0;
867
872
for (let i = 0 ; i < 10 ; i++ ) {
868
873
pool .runTask ({ a: 42 , b: 100 }, (err , result ) => {
869
874
console .log (i, err, result);
870
- if (++ finished === 10 )
871
- pool .close ();
875
+ if (++ finished === 10 ) pool .close ();
872
876
});
873
877
}
874
878
` ` `
@@ -888,9 +892,12 @@ import { createServer } from 'node:http';
888
892
import { AsyncResource , executionAsyncId } from ' node:async_hooks' ;
889
893
890
894
const server = createServer ((req , res ) => {
891
- req .on (' close' , AsyncResource .bind (() => {
892
- // Execution context is bound to the current outer scope.
893
- }));
895
+ req .on (
896
+ ' close' ,
897
+ AsyncResource .bind (() => {
898
+ // Execution context is bound to the current outer scope.
899
+ })
900
+ );
894
901
req .on (' close' , () => {
895
902
// Execution context is bound to the scope that caused 'close' to emit.
896
903
});
@@ -903,9 +910,12 @@ const { createServer } = require('node:http');
903
910
const { AsyncResource , executionAsyncId } = require (' node:async_hooks' );
904
911
905
912
const server = createServer ((req , res ) => {
906
- req .on (' close' , AsyncResource .bind (() => {
907
- // Execution context is bound to the current outer scope.
908
- }));
913
+ req .on (
914
+ ' close' ,
915
+ AsyncResource .bind (() => {
916
+ // Execution context is bound to the current outer scope.
917
+ })
918
+ );
909
919
req .on (' close' , () => {
910
920
// Execution context is bound to the scope that caused 'close' to emit.
911
921
});
0 commit comments