Navigation

AsyncContext and AsyncLocalStorage

If LazyPromise naively ignored the Node’s AsyncLocalStorage (the same will apply to the upcoming cross-platform version AsyncContext), then in

all([lazyPromiseA, lazyPromiseB]).subscribe({ resolve: foo });

foo could run in a different async context depending on which lazy promise resolves first. Instead, LazyPromise runs the constructor callback, the consumer’s resolve/reject handlers, and the teardown logic in the context where subscribe was called. As a consequence, async context propagates upstream but not downstream, and generator functions behave the same way as async-await:

const als = new AsyncLocalStorage<string>();

const lazyPromise = fromGen(function* () {
  console.log(als.getStore()); // "a"
  yield* new LazyPromise<void>((sink) => {
    als.run("b", () => {
      sink.resolve();
    });
  });
  console.log(als.getStore()); // Still "a"
});

als.run("a", () => {
  lazyPromise.subscribe();
});

One way to think of async context is as an implicit counterpart of dependency injection.