@@ -579,6 +579,110 @@ const server = net.createServer((conn) => {
579579Promise contexts may not get valid ` triggerAsyncId ` s by default. See
580580the section on [ promise execution tracking] [ ] .
581581
582+ ### Class: ` AsyncLocal `
583+
584+ <!-- YAML
585+ added: REPLACEME
586+ -->
587+
588+ This class can be used to store a value which follows asynchronous execution
589+ flow. Any value set on an ` AsyncLocal ` instance is propagated to any callback
590+ or promise executed within the flow. Because of that, a continuation local
591+ storage can be build with an ` AsyncLocal ` instance. This API is similar to
592+ thread local storage in other runtimes and languages.
593+
594+ The implementation relies on async hooks to follow the execution flow.
595+ So, if an application or a library does not play nicely with async hooks,
596+ the same problems will be seen with the ` AsyncLocal ` API. In order to fix
597+ such issues the ` AsyncResource ` API should be used.
598+
599+ The following example shows how to use ` AsyncLocal ` to build a simple logger
600+ that assignes ids to HTTP requests and includes them into messages logged
601+ within each request.
602+
603+ ``` js
604+ const http = require (' http' );
605+ const { AsyncLocal } = require (' async_hooks' );
606+
607+ const asyncLocal = new AsyncLocal ();
608+
609+ function print (msg ) {
610+ const id = asyncLocal .get ();
611+ console .log (` ${ id !== undefined ? id : ' -' } :` , msg);
612+ }
613+
614+ let idSeq = 0 ;
615+ http .createServer ((req , res ) => {
616+ asyncLocal .set (idSeq++ );
617+ print (' start' );
618+ setImmediate (() => {
619+ print (' finish' );
620+ res .end ();
621+ });
622+ }).listen (8080 );
623+
624+ http .get (' http://localhost:8080' );
625+ http .get (' http://localhost:8080' );
626+ // Prints:
627+ // 0: start
628+ // 1: start
629+ // 0: finish
630+ // 1: finish
631+ ```
632+
633+ #### ` new AsyncLocal() `
634+
635+ Creates a new instance of ` AsyncLocal ` .
636+
637+ ### ` asyncLocal.get() `
638+
639+ * Returns: {any}
640+
641+ Returns the value of the ` AsyncLocal ` in current execution context,
642+ or ` undefined ` if the value is not set or the ` AsyncLocal ` was removed.
643+
644+ ### ` asyncLocal.set(value) `
645+
646+ * ` value ` {any}
647+
648+ Sets the value for the ` AsyncLocal ` within current execution context.
649+
650+ Once set, the value will be kept through the subsequent asynchronous calls,
651+ unless overridden by calling ` asyncLocal.set(value) ` :
652+
653+ ``` js
654+ const asyncLocal = new AsyncLocal ();
655+
656+ setImmediate (() => {
657+ asyncLocal .set (' A' );
658+
659+ setImmediate (() => {
660+ console .log (asyncLocal .get ());
661+ // Prints: A
662+
663+ asyncLocal .set (' B' );
664+ console .log (asyncLocal .get ());
665+ // Prints: B
666+ });
667+
668+ console .log (asyncLocal .get ());
669+ // Prints: A
670+ });
671+ ```
672+
673+ If the ` AsyncLocal ` was removed before this call is made,
674+ [ ` ERR_ASYNC_LOCAL_CANNOT_SET_VALUE ` ] [ ] is thrown.
675+
676+ ### ` asyncLocal.remove() `
677+
678+ When called, removes all values stored in the ` AsyncLocal ` and disables
679+ callbacks for the internal ` AsyncHook ` instance. Calling ` asyncLocal.remove() `
680+ multiple times will have no effect.
681+
682+ Any subsequent ` asyncLocal.get() ` calls will return ` undefined ` .
683+ Any subsequent ` asyncLocal.set(value) ` calls will throw
684+ [ ` ERR_ASYNC_LOCAL_CANNOT_SET_VALUE ` ] [ ] .
685+
582686## Promise execution tracking
583687
584688By default, promise executions are not assigned ` asyncId ` s due to the relatively
@@ -868,3 +972,4 @@ for (let i = 0; i < 10; i++) {
868972[ PromiseHooks ] : https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit
869973[ `Worker` ] : worker_threads.html#worker_threads_class_worker
870974[ promise execution tracking ] : #async_hooks_promise_execution_tracking
975+ [ `ERR_ASYNC_LOCAL_CANNOT_SET_VALUE` ] : errors.html#ERR_ASYNC_LOCAL_CANNOT_SET_VALUE
0 commit comments