From a3d4c950d63f5a81fc802324a9aab42057343108 Mon Sep 17 00:00:00 2001 From: flakey5 <73616808+flakey5@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:12:00 -0800 Subject: [PATCH] lib: add AsyncLocalStorage.bind() and .snapshot() --- doc/api/async_context.md | 50 +++++++++++++++++++ lib/async_hooks.js | 8 +++ .../parallel/test-async-local-storage-bind.js | 17 +++++++ .../test-async-local-storage-snapshot.js | 16 ++++++ 4 files changed, 91 insertions(+) create mode 100644 test/parallel/test-async-local-storage-bind.js create mode 100644 test/parallel/test-async-local-storage-snapshot.js diff --git a/doc/api/async_context.md b/doc/api/async_context.md index c3f287e690955c..f9896c0a2c692c 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -136,6 +136,56 @@ changes: Creates a new instance of `AsyncLocalStorage`. Store is only provided within a `run()` call or after an `enterWith()` call. +### Static method: `AsyncLocalStorage.bind(fn)` + + + +> Stability: 1 - Experimental + +* `fn` {Function} The function to bind to the current execution context. +* Returns: {Function} A new function that calls `fn` within the captured + execution context. + +Binds the given function to the current execution context. + +### Static method: `AsyncLocalStorage.snapshot()` + + + +> Stability: 1 - Experimental + +* Returns: {Function} A new function with the signature + `(fn: (...args) : R, ...args) : R`. + +Captures the current execution context and returns a function that accepts a +function as an argument. Whenever the returned function is called, it +calls the function passed to it within the captured context. + +```js +const asyncLocalStorage = new AsyncLocalStorage(); +const runInAsyncScope = asyncLocalStorage.run(123, () => asyncLocalStorage.snapshot()); +const result = asyncLocalStorage.run(321, () => runInAsyncScope(() => asyncLocalStorage.getStore())); +console.log(result); // returns 123 +``` + +AsyncLocalStorage.snapshot() can replace the use of AsyncResource for simple +async context tracking purposes, for example: + +```js +class Foo { + #runInAsyncScope = AsyncLocalStorage.snapshot(); + + get() { return this.#runInAsyncScope(() => asyncLocalStorage.getStore()); } +} + +const foo = asyncLocalStorage.run(123, () => new Foo()); +console.log(asyncLocalStorage.run(321, () => foo.get())); // returns 123 +``` + ### `asyncLocalStorage.disable()`