Blog / How Do I Async?

How Do I Async?

Several modern languages implement variants of the async/await pattern, but it can be a bit difficult to drill down to the basic syntax. A lot of the documentation on this pattern assumes that the concept is brand new to the reader, and they have to be introduced gently, lest they incur psychic damage. As such, here are some barebones examples of async/await in JavaScript, Swift and Kotlin.

Comparison Table

Language Signature Invocation
JavaScript async function myFunction() { await myFunction()
Swift func myFunction() async { await myFunction()
Kotlin suspend fun myFunction() { myFunction()

JavaScript

Note that unless you're using web workers, your code will always run on the same thread. However, native asynchronous JavaScript functions like fetch() will often run on background threads.

// Define an async function
async function downloadFile(path, type) {
	// Download logic goes here
	return file;
}

// Call an async function from another async function
async function downloadPng(path) {
	return await downloadFile(path, "image/png");
}

// Call an async function from a synchronous function
function reloadLogo(logoPath) {
	// Async functions implicitly return a promise when used without "await"
	downloadPng(logoPath).then((logo) => {
		// Do something with the logo
	});
}

// Await a promise
async function wait(duration) {
	// Regular promises can be awaited
	await new Promise((resolve) => window.setTimeout(duration, resolve));
}

Swift

// Define an async function
func downloadFile(from path: String, ofType type: String) async -> File {
	// Download logic goes here
	return file
}

// Call an async function from another async function
func downloadPng(from path: String) async -> File {
	return await downloadFile(from: path, ofType: "image/png")
}

// Call an async function from a synchronous function
func reloadLogo(logoPath: String) {
	// The new task will be run as an asynchronous function in a background thread
	Task {
		let logo = await downloadPng(from: logoPath)
		// Do something with the logo
	}
}

Kotlin

Note that Kotlin expects you to choose a dispatcher for your coroutine. These include:

  • Main Dispatcher: For tasks that should run on the main thread.
  • IO Dispatcher: For longer IO tasks, such as downloading data or saving to the disk.
  • Default Dispatcher: For computationally expensive processing that would otherwise block the main thread.

There's also an Unconfined Dispatcher, but it's a bit complicated and outside the scope of this article.

// Define an async function
suspend fun downloadFile(path: String, type: String): File {
	// Download logic goes here
	return file
}

// Call an async function from another async function
suspend func downloadPng(path: String) -> File {
	// Kotlin does not require you to use the "await" keyword
	return downloadFile(path, "image/png")
}

// Call an async function from a synchronous function
func reloadLogo(logoPath: String) {
	// The new coroutine will be run as an asynchronous function on an IO thread
	CoroutineScope(Dispatchers.IO).launch {
		val logo = downloadPng(logoPath)
		// Do something with the logo
	}
}

Container Query Units >