Skip to content

Commit 17db79d

Browse files
authored
Update README.md (#7)
1 parent a51a21b commit 17db79d

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

README.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,54 @@ a scope out of sync with the lexical scoping, an alternative proposal is to
354354
specialize the handling of async context variables in `using` declarations as
355355
follows:
356356

357-
// TODO: snek
357+
```js
358+
class AsyncVariableScope {
359+
#asyncVar;
360+
#value;
361+
#previousContextMapping;
362+
363+
constructor(asyncVar, value) {
364+
this.#asyncVar = asyncVar;
365+
this.#value = value;
366+
}
367+
368+
// if present, slot called by `using` instead of @@enter
369+
[[UsingEnter]]() {
370+
const asyncContextMapping = snapshot + { [[AsyncContextKey]]: this.[[AsyncVariable]], [[AsyncContextValue]]: this.[[Value]] };
371+
this.#previousContextMapping = AsyncContextSwap(asyncContextMapping);
372+
}
373+
374+
// if present, slot called by `using` instead of @@dispose
375+
[[UsingDispose]]() {
376+
AsyncContextSwap(this.#previousContextMapping);
377+
}
378+
}
379+
```
380+
381+
This can then be used in user code with subclassing:
382+
383+
```js
384+
class SpanRef extends AsyncVariableScopable {
385+
#span;
386+
387+
constructor(tracer, span) {
388+
super(tracer.asyncContext, span);
389+
this.#span = span;
390+
}
391+
392+
// span apis here, etc...
393+
setAttribute(name, value) { this.#span.setAttribute(name, value); }
394+
}
395+
396+
class Tracer {
397+
startSpan() {
398+
const span = this.createSpan();
399+
return new SpanRef(this, span);
400+
}
401+
}
402+
403+
using span = tracer.startSpan();
404+
```
358405

359406
# Use cases
360407

0 commit comments

Comments
 (0)