AsyncLocalStorage
Cloudflare Workersは、非同期操作を通じて一貫性を保つメモリ内ストアを作成するためのNode.jsのAsyncLocalStorage ↗ APIのサブセットの実装を提供します。
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();-
new AsyncLocalStorage(): AsyncLocalStorage- 新しい
AsyncLocalStorageインスタンスを返します。
- 新しい
-
getStore(): any- 現在のストアを返します。
asyncLocalStorage.run()を呼び出して初期化された非同期コンテキストの外で呼び出された場合、undefinedを返します。
- 現在のストアを返します。
-
run(storeany, callbackfunction, …argsarguments): any- コンテキスト内で関数を同期的に実行し、その戻り値を返します。ストアはコールバック関数の外ではアクセスできません。ストアはコールバック内で作成された任意の非同期操作にアクセス可能です。オプションの
argsはコールバック関数に渡されます。コールバック関数がエラーをスローした場合、run()もエラーをスローします。
- コンテキスト内で関数を同期的に実行し、その戻り値を返します。ストアはコールバック関数の外ではアクセスできません。ストアはコールバック内で作成された任意の非同期操作にアクセス可能です。オプションの
-
exit(callbackfunction, …argsarguments): any- コンテキストの外で関数を同期的に実行し、その戻り値を返します。このメソッドは、
storeの値をundefinedに設定してrun()を呼び出すことと同等です。
- コンテキストの外で関数を同期的に実行し、その戻り値を返します。このメソッドは、
-
AsyncLocalStorage.bind(fn): functionbind()が呼び出されたときの現在の非同期コンテキストをキャプチャし、渡された関数を呼び出す前にそのコンテキストに入る関数を返します。
-
AsyncLocalStorage.snapshot(): functionsnapshot()が呼び出されたときの現在の非同期コンテキストをキャプチャし、指定された関数を呼び出す前にそのコンテキストに入る関数を返します。
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();let idSeq = 0;
export default { async fetch(req) { return asyncLocalStorage.run(idSeq++, () => { // 一部の非同期アクティビティをシミュレート... await scheduler.wait(1000); return new Response(asyncLocalStorage.getStore()); }); }};APIは、複数のAsyncLocalStorageインスタンスを同時に使用することをサポートしています。
import { AsyncLocalStorage } from 'node:async_hooks';
const als1 = new AsyncLocalStorage();const als2 = new AsyncLocalStorage();
export default { async fetch(req) { return als1.run(123, () => { return als2.run(321, () => { // 一部の非同期アクティビティをシミュレート... await scheduler.wait(1000); return new Response(`${als1.getStore()}-${als2.getStore()}`); }); }); }};Promiseが拒否され、拒否が未処理の場合、非同期コンテキストは'unhandledrejection'イベントハンドラーに伝播します:
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();let idSeq = 0;
addEventListener('unhandledrejection', (event) => { console.log(asyncLocalStorage.getStore(), '未処理の拒否!');});
export default { async fetch(req) { return asyncLocalStorage.run(idSeq++, () => { // 未処理の拒否を引き起こす! throw new Error('boom'); }); }};import { AsyncLocalStorage } from 'node:async_hooks';
const als = new AsyncLocalStorage();
function foo() { console.log(als.getStore()); }function bar() { console.log(als.getStore()); }
const oneFoo = als.run(123, () => AsyncLocalStorage.bind(foo));oneFoo(); // 123を出力
const snapshot = als.run('abc', () => AsyncLocalStorage.snapshot());snapshot(foo); // 'abc'を出力snapshot(bar); // 'abc'を出力import { AsyncLocalStorage } from 'node:async_hooks';
const als = new AsyncLocalStorage();
class MyResource { #runInAsyncScope = AsyncLocalStorage.snapshot();
doSomething() { this.#runInAsyncScope(() => { return als.getStore(); }); }};
const myResource = als.run(123, () => new MyResource());console.log(myResource.doSomething()); // 123を出力AsyncResource ↗クラスは、ユーザーが独自の非同期コンテキストを作成できるNode.jsの非同期コンテキスト追跡APIのコンポーネントです。AsyncResourceから拡張されたオブジェクトは、プロミスと同様に非同期コンテキストを伝播することができます。
AsyncLocalStorage.snapshot()とAsyncLocalStorage.bind()がより良いアプローチを提供することに注意してください。AsyncResourceはNode.jsとの後方互換性のために提供されています。
import { AsyncResource, AsyncLocalStorage } from 'node:async_hooks';
const als = new AsyncLocalStorage();
class MyResource extends AsyncResource { constructor() { // タイプ文字列はNode.jsによって要求されますが、Workersでは使用されません。 super('MyResource'); }
doSomething() { this.runInAsyncScope(() => { return als.getStore(); }); }};
const myResource = als.run(123, () => new MyResource());console.log(myResource.doSomething()); // 123を出力-
new AsyncResource(typestring, optionsAsyncResourceOptions): AsyncResource- 新しい
AsyncResourceを返します。重要なことに、コンストラクタ引数はNode.jsのAsyncResourceの実装では必要ですが、Workersでは使用されません。
- 新しい
-
AsyncResource.bind(fnfunction, typestring, thisArgany)- 指定された関数を現在の非同期コンテキストにバインドします。
-
asyncResource.bind(fnfunction, thisArgany)- 指定された関数をこの
AsyncResourceに関連付けられた非同期コンテキストにバインドします。
- 指定された関数をこの
-
asyncResource.runInAsyncScope(fnfunction, thisArgany, …argsarguments)- 指定された引数で提供された関数をこの
AsyncResourceに関連付けられた非同期コンテキストで呼び出します。
- 指定された引数で提供された関数をこの
-
Workersによって提供される
AsyncLocalStorageの実装は、意図的にasyncLocalStorage.enterWith()↗およびasyncLocalStorage.disable()↗メソッドのサポートを省略しています。 -
Workersは、Node.jsの
AsyncLocalStorageの実装が構築されている完全なasync_hooks↗ APIを実装していません。 -
Workersは、Node.jsによって許可される明示的に識別されたトリガーコンテキストを持つ
AsyncResourceを作成する機能を実装していません。これは、新しいAsyncResourceが常に作成された非同期コンテキストにバインドされることを意味します。 -
Thenables(
then()メソッドを公開する非Promiseオブジェクト)は、AsyncLocalStorageを使用する際に完全にはサポートされていません。Thenablesを扱う場合は、代わりにAsyncLocalStorage.snapshot()↗を使用して現在のコンテキストのスナップショットをキャプチャしてください。