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