From f1b79828bc4215365ee31e3fd052c1937426f1e4 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() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/46387 Reviewed-By: Stephen Belanger Reviewed-By: Chengzhong Wu Reviewed-By: Gerhard Stöbich --- 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 85507cfadc8f1a..ed2de575e92106 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -134,6 +134,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()`