@@ -509,6 +509,9 @@ const server = net.createServer(function onConnection(conn) {
509
509
});
510
510
```
511
511
512
+ Note that promise contexts may not get precise executionAsyncIds by default.
513
+ See the section on [ promise execution tracking] [ ] .
514
+
512
515
#### ` async_hooks.triggerAsyncId() `
513
516
514
517
* Returns: {number} The ID of the resource responsible for calling the callback
@@ -531,6 +534,57 @@ const server = net.createServer((conn) => {
531
534
});
532
535
```
533
536
537
+ Note that promise contexts may not get valid triggerAsyncIds by default. See
538
+ the section on [ promise execution tracking] [ ] .
539
+
540
+ ## Promise execution tracking
541
+
542
+ By default, promise executions are not assigned asyncIds due to the relatively
543
+ expensive nature of the [ promise introspection API] [ PromiseHooks ] provided by
544
+ V8. This means that programs using promises or ` async ` /` await ` will not get
545
+ correct execution and trigger ids for promise callback contexts by default.
546
+
547
+ Here's an example:
548
+
549
+ ``` js
550
+ const ah = require (' async_hooks' );
551
+ Promise .resolve (1729 ).then (() => {
552
+ console .log (` eid ${ ah .executionAsyncId ()} tid ${ ah .triggerAsyncId ()} ` );
553
+ });
554
+ // produces:
555
+ // eid 1 tid 0
556
+ ```
557
+
558
+ Observe that the ` then ` callback claims to have executed in the context of the
559
+ outer scope even though there was an asynchronous hop involved. Also note that
560
+ the triggerAsyncId value is 0, which means that we are missing context about the
561
+ resource that caused (triggered) the ` then ` callback to be executed.
562
+
563
+ Installing async hooks via ` async_hooks.createHook ` enables promise execution
564
+ tracking. Example:
565
+
566
+ ``` js
567
+ const ah = require (' async_hooks' );
568
+ ah .createHook ({ init () {} }).enable (); // forces PromiseHooks to be enabled.
569
+ Promise .resolve (1729 ).then (() => {
570
+ console .log (` eid ${ ah .executionAsyncId ()} tid ${ ah .triggerAsyncId ()} ` );
571
+ });
572
+ // produces:
573
+ // eid 7 tid 6
574
+ ```
575
+
576
+ In this example, adding any actual hook function enabled the tracking of
577
+ promises. There are two promises in the example above; the promise created by
578
+ ` Promise.resolve() ` and the promise returned by the call to ` then ` . In the
579
+ example above, the first promise got the asyncId 6 and the latter got asyncId 7.
580
+ During the execution of the ` then ` callback, we are executing in the context of
581
+ promise with asyncId 7. This promise was triggered by async resource 6.
582
+
583
+ Another subtlety with promises is that ` before ` and ` after ` callbacks are run
584
+ only on chained promises. That means promises not created by ` then ` /` catch ` will
585
+ not have the ` before ` and ` after ` callbacks fired on them. For more details see
586
+ the details of the V8 [ PromiseHooks] [ ] API.
587
+
534
588
## JavaScript Embedder API
535
589
536
590
Library developers that handle their own asynchronous resources performing tasks
@@ -655,3 +709,5 @@ constructor.
655
709
[ `destroy` callback ] : #async_hooks_destroy_asyncid
656
710
[ `init` callback ] : #async_hooks_init_asyncid_type_triggerasyncid_resource
657
711
[ Hook Callbacks ] : #async_hooks_hook_callbacks
712
+ [ PromiseHooks ] : https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk
713
+ [ promise execution tracking ] : #async_hooks_promise_execution_tracking
0 commit comments