← Cloudflare Workers / workers / runtime-apis / nodejs
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- Синхронно выполняет функцию вне контекста и возвращает её результат. Этот метод эквивалентен вызову
run()наstoreзначение, равноеundefined.
- Синхронно выполняет функцию вне контекста и возвращает её результат. Этот метод эквивалентен вызову
Статические методы
-
AsyncLocalStorage.bind(fn): function- Захватывает асинхронный контекст, который является текущим в момент, когда
bind()вызывается и возвращает функцию, которая входит в этот контекст перед вызовом переданной функции.
- Захватывает асинхронный контекст, который является текущим в момент, когда
-
AsyncLocalStorage.snapshot(): function- Захватывает асинхронный контекст, который является текущим в момент, когда
snapshot()вызывается и возвращает функцию, которая входит в этот контекст перед вызовом заданной функции.
- Захватывает асинхронный контекст, который является текущим в момент, когда
Примеры
Слушатель событий fetch
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();
let idSeq = 0;
export default {
async fetch(req) {
return asyncLocalStorage.run(idSeq++, () => {
// Simulate some async activity...
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, () => {
// Simulate some async activity...
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(), "unhandled rejection!");
});
export default {
async fetch(req) {
return asyncLocalStorage.run(idSeq++, () => {
// Cause an unhandled rejection!
throw new Error("boom");
});
},
};AsyncLocalStorage.bind() и AsyncLocalStorage.snapshot()
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(); // prints 123
const snapshot = als.run("abc", () => AsyncLocalStorage.snapshot());
snapshot(foo); // prints 'abc'
snapshot(bar); // prints '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()); // prints 123AsyncResource
AsyncResource ↗ класс является частью API отслеживания асинхронного контекста Node.js, который позволяет создавать собственные асинхронные контексты. Объекты, расширяющие AsyncResource способны передавать асинхронный контекст почти так же, как promises.
Обратите внимание, что AsyncLocalStorage.snapshot() и AsyncLocalStorage.bind() предлагают более удачный подход. AsyncResource предоставляется исключительно для обратной совместимости с Node.js.
Конструктор
import { AsyncResource, AsyncLocalStorage } from "node:async_hooks";
const als = new AsyncLocalStorage();
class MyResource extends AsyncResource {
constructor() {
// The type string is required by Node.js but unused in Workers.
super("MyResource");
}
doSomething() {
this.runInAsyncScope(() => {
return als.getStore();
});
}
}
const myResource = als.run(123, () => new MyResource());
console.log(myResource.doSomething()); // prints 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.
- Вызывает переданную функцию с указанными аргументами в асинхронном контексте, связанном с этим
Важные замечания
-
AsyncLocalStorageреализация, предоставляемая Workers, намеренно не поддерживаетasyncLocalStorage.enterWith()↗ иasyncLocalStorage.disable()↗ методы. -
Workers не реализует полную версию
async_hooks↗ API, на основе которого реализация Node.js дляAsyncLocalStorageсобран. -
Workers не реализует возможность создания
AsyncResourceс явно указанным контекстом триггера, как это допускает Node.js. Это означает, что новыйAsyncResourceвсегда привязан к асинхронному контексту, в котором он был создан. -
Thenable-объекты (объекты, не являющиеся Promise, но предоставляющие
then()метод) не полностью поддерживаются при использованииAsyncLocalStorage. При работе с thenable-объектами вместо этого используйтеAsyncLocalStorage.snapshot()↗ чтобы сделать снимок текущего контекста.