Sep 17, 2020

Async as Generator

In the good old days, async code was written by creating new threads, and using lock statements to make sure that multiple threads didn't disrupt each other when accessing or writing data. In modern time I have a feeling that the field of async code is becoming a more integral part of programming languages. Different languages help the programmer by creating useful abstractions on top of async code, that allows the coder to write easy to read async code that gets compiled into performant code following good conventions for how to do async code.

In todays post I want to take a look at Javascript and the async, await that is available in there. It was a feature that I first saw in C#, but that is now (since quite some time) reaching other languages. Now, I don't know if this is how async code actually works under the hood for Javascript, but I wish to rewrite the async as an implementation using generators.

Imagine the following method:

async function downloadAndCalculate() {
	const number = await api.get();
	return number * 2
}

Now, let's rewrite this to a generator:

function* downloadAndCalculate() {
	const number = yield api.get();
	return number * 2;
}
function async(func) {
	const generator = func();
	return new Promise((resolve, reject) => {
		function iterate(iterator) {
			if(iterator.done) {
				resolve(iterator.val);
			} else {
				iterator.value.then( val => {
					iterate(generator.next(val));
				}, reject);
			}
		}
		iterate(generator.next());
	});

}

this means that calling async(downloadAndCalculate) would be equivalent of calling the async version of downloadAndCalculate.

Granted, I haven't actually test run the code, but the principle should be something similar to what has been written here.