Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active March 18, 2021 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rauschma/470a3077601e1af065b4740d35a19573 to your computer and use it in GitHub Desktop.
Save rauschma/470a3077601e1af065b4740d35a19573 to your computer and use it in GitHub Desktop.

Dual mode code (that works both synchronously and asynchronously)

My use case: a Markdown parser that should work both synchronously and asynchronously. The latter forces the invoking code to switch to async, which is overkill when parsing simple strings.

Currently the parser is based on async generators.

Potential solution 1: CSP (communicating sequential processes) and generators

I did some experiments with CSP.

Approach:

  • Replace async generators with sync generators.
  • Use yield instead of await.
  • Use a queue for output instead of yield.

The generators are controlled by a driver. There are two versions of the driver/queue combo:

  • Async version: The queue is based on Promises. The driver awaits when there is a yield.
  • Sync version: The queue returns values (directly or inside lightweight wrappers). The driver mostly just passes the values on.

Alas, I was never completely happy with the results of my experiments. The code always felt off.

Potential solution 2: duplicate code

  • Original code is based on async iteration and asynchronous helpers (functions and/or objects).
  • A synchronous version is produced by removing every “async” from the core code and by replacing the async helpers with synchronous ones.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment