# Await/Async in Unity

# Async/Await in C# Unity

#### Preface

The original content is from the author Santosh Parihar from [Medium.com](https://medium.com/@sonusprocks/async-await-in-c-unity-explained-in-easy-words-571ebb6a9369). It has been modified and updated for use in this wiki.

<p class="callout warning">This is an **advanced** topic! You should have an understanding of Object Oriented Programming in C# as well as an understanding behind C# Delegates.</p>

#### Getting Started

<div id="bkmrk-"></div><div class="h k" id="bkmrk--1"><div>  
</div></div>***<span class="ns">Lets understand Synchronous Operations first:</span>***

In software development, synchronous operations refer to tasks that are executed in a sequential, blocking manner. This means that one task is completed before the next one begins, and each operation waits for the previous one to finish. In synchronous execution, the program’s flow is linear, and tasks are processed one after the other. It’s like standing in a queue: each person must wait for the one in front to finish before proceeding.

*Unity’s Main Thread :*

Unity operates primarily on a single thread known as the “main thread” or “game loop”. This main thread is responsible for several critical tasks, including:

- Input Handling, Game Logic Update,Physics Simulation, Rendering and Repeat.
- The loop continues these steps continuously, maintaining the real-time nature of the game.

***Unity often requires asynchronous operations due to the following key reasons:***

*1. Preventing Main Thread Blocking:*

- In synchronous operations, if a task takes a long time to complete (like loading a large file or making a network request), it can cause the main thread to become unresponsive. This results in the game freezing or stuttering, leading to a poor user experience.
- Asynchronous operations allow you to perform these time-consuming tasks in the background, ensuring that the main thread remains free to handle other critical tasks like rendering, input processing, and game logic.

2\. *Handling Concurrent Tasks:*

- Games often need to perform multiple tasks simultaneously, like loading assets, processing AI behavior, and handling network communication. Asynchronous operations enable you to manage these tasks concurrently without one task blocking the others.

3\. *Network Communication:*

- When making network requests, especially over the internet, the response time can vary. Asynchronous operations allow the game to continue functioning while waiting for data from the network, preventing the game from feeling sluggish.

4\. *Error Handling:*

- Asynchronous operations often offer better error handling. If something goes wrong during a synchronous operation, it can disrupt the entire process and may not be easy to recover from. With asynchronous operations, errors can be caught and handled more gracefully, allowing the game to continue running without catastrophic failures.

```c#
async Task HandleAsyncOperation()
{
    try
    {
        // Asynchronous operation
        await SomeAsyncTask();
    }
    catch (Exception e)
    {
        Debug.Log($"error : {e.Message}");
    }
}
```


#### <span class="al">Here’s a simplified explanation and different examples of async/await for beginners :</span>

To use async/await, you first need to declare your method as `async`. This tells the compiler that the method can return an `async Task` object. You can then use the `await` keyword to wait for an asynchronous operation to complete.

```c#
using System.Threading.Tasks;
using UnityEngine;

public class AsyncExample : MonoBehaviour
{
    async void Start()
    {
        Debug.Log("Start of the method");

        await SomeAsyncOperation();

        Debug.Log("After the async operation");
    }

    async Task SomeAsyncOperation()
    {
        await Task.Delay(2000); // Simulating a time-consuming operation
    }
}
```

##### <span class="mw gu">Example 1</span>

<span class="mw gu">The following code loads an asset, creates a new object with the asset, and then moves the object to a specific location:</span>

```c#
 void Start()
 {
   SpawnPlayer();
 }

async void SpawnPlayer()
{

 GameObject player = await AssetDatabase.LoadAssetAsync("Assets/Player.asset");
 GameObject playerBody= new GameObject(playerBody);
 await playerBody.transform.position = new Vector3(1, 5, 4);

}
```

##### Example 2

Imagine you’re a magician performing a series of magic tricks. Each trick requires some setup time, and you want to perform them one after another without making the audience wait too long between tricks.

Using async/await, you can perform multiple tricks concurrently and ensure a smooth flow of your performance. Let’s see how it works:

```c#
using System;
using UnityEngine;
using System.Threading.Tasks;

public class Magician : MonoBehaviour
{
    public async Task PerformMagicShow()
    {
        Debug.Log("Preparing for the magic show...");

        Task trick1Task = PerformTrick("Card Trick");
        Task trick2Task = PerformTrick("Coin Trick");

        // While the tricks are being prepared, you can engage the audience
        Debug.Log("Engaging the audience with some jokes...");

        // Await the completion of each trick
        await trick1Task;
        Debug.Log("Card Trick performed!");

        await trick2Task;
        Debug.Log("Coin Trick performed!");

        Debug.Log("Magic show completed!");
    }

    private async Task PerformTrick(string trickName)
    {
        Debug.Log($"Preparing for {trickName}...");

        // Simulate the time it takes to set up the trick
        await Task.Delay(3000); // 3 seconds

        Debug.Log($"Performing {trickName}!");
    }

    public async Task StartMagic( )
    {
        await PerformMagicShow();
    }

    public void Start()
    {
         StartMagic();
    }

 }
```

In this example, the `Magician` class represents a magician performing a magic show. Each trick is represented by the `PerformTrick` method, which is called with the name of the trick.

Inside the `PerformMagicShow` method, two tricks (`Card Trick` and `Coin Trick`) are initiated concurrently using `PerformTrick` and stored in separate `Task` objects (`trick1Task` and `trick2Task`).

While the tricks are being prepared, you engage the audience with jokes, giving them an entertaining experience during the setup phase.

By assigning `PerformTrick("Card Trick")` to the `trick1Task` variable, you are creating a `Task` object that represents the asynchronous operation of performing card trick. However, at this point, the `PerformTrick("Card Trick")` method will start executing, and the program will proceed to the next line without waiting for the 3-second delay to complete.

The execution will continue to the line `Task trick2Task = PerformTrick("Coin Trick");`, which starts the `PerformTrick("Coin Trick")` method. Similarly, this method contains an asynchronous operation simulated by `Task.Delay(3000)`. Here again, the program will start executing this method, but it won't wait for the 3-second delay to finish.

The line await `trick1Task;` will pause the execution of the PerformMagicShow`()` method and wait until the `trick1Task` is completed before moving on to the next line of code.

When you use the `await` keyword, it essentially tells the program to pause at that point and allow other tasks to continue executing while it waits for the awaited task to complete. In this case, it will wait for the `trick1Task` to finish.

Once the `trick1Task` is completed, the program will resume execution at the next line after the `await` statement. In this code example, it will print "Card Trick performed!" to the console.

So, the `await` keyword ensures that the subsequent code is not executed until the awaited task (in this case, `trick1Task`) has finished its execution.

Then, using `await`, the program waits for each trick to complete before moving on to the next line. Once a trick is completed, a corresponding message is printed to the console.

Finally, when all the tricks are finished, the program prints a completion message, indicating that the magic show is complete.

This playful example demonstrates how async/await can be used to perform multiple tasks concurrently, allowing you to keep the audience engaged while seamlessly transitioning between different tricks during a magic show.

<p class="callout info"><span class="mw gu">Unity is single threaded. Coroutines are useful for executing methods over a number of frames.  
Async methods are useful for executing methods after a given task has finished.  
</span></p>

Unity’s main thread is single-threaded, meaning that all Unity-related operations, such as rendering and updating the game, are handled on that thread. However, async/await can still be beneficial in Unity for handling certain types of tasks, even if they don’t run on separate threads.

The key idea is that while the async operations themselves may not run on separate threads, they still allow the Unity main thread to continue processing other tasks and remain responsive.

In summary, while Unity’s main thread is single-threaded, async/await can still be utilized in Unity to handle async operations in a non-blocking manner, allowing the main thread to continue processing other tasks while waiting for the completion of the async operations.

<p class="callout info">When utilizing coroutines, a feature in Unity, they will automatically stop running as soon as you stop the Unity editor or the game ends. However, when using threads, they can continue running in the background even after stopping the Unity editor. To ensure proper handling, it becomes necessary to manually stop the thread when stopping the Unity editor to prevent any unintended background execution.</p>

To solve the problem we will use Task Cancellation feature of c#, you can read more about it here :

[https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation](https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation)

```c#
public class TestAsync : MonoBehaviour
{

    private CancellationTokenSource token;

    private void OnEnable()
    {
        token = new CancellationTokenSource();
        Debug.Log(" task , on enable");

        // Start the work in a separate task
        Task.Run(DoWork);
    }

    private void OnDisable()
    {
        Debug.Log(" task , on disable , task cancel");

        // Cancel the task when the script is disabled
        token.Cancel();
    }

    private async void DoWork()
    {
        Debug.Log(" task , do work");
        await Task.Run(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Debug.Log("Hello");
                if (token.IsCancellationRequested)
                {
                    return;
                }
            }
        }, token.Token);

        if (token.IsCancellationRequested)
        {
            Debug.Log("task was cancelled.");
            return; // further code will not be executed
        }

        // Code to be executed after the task completes successfully
        Debug.Log("task completed successfully.");
    }
}
```

Hope you understood the concept.

# Converting A Coroutine To An Async

#### Preface

The original content is from the author Michael Quinn from [Medium.com](https://medium.com/unity-coder-corner/unity-converting-a-coroutine-to-an-async-and-never-looking-back-b5a78f91049f). It has been modified and updated for use in this wiki.

<p class="callout warning">This is an **advanced** topic! You should have an understanding of Object Oriented Programming in C# as well as an understanding behind C# Delegates.</p>

<p class="callout info">I could have translated the code below into code snippets, but I found it more important to physically type what's needed for the sake of understanding.</p>

#### About

Coroutines are amazing ways to sequence logic together over many frames. Asynchronous programming, or **async**, allows the code to similarly be split over multiple frames, but allows for multithreading which has the benefit of logic being concurrently executed instead of sequentially.

####  

#### The Coroutine Way

I have a very simple example that rotates cubes for a certain amount of time.

<div class="go gp ga gq gr" id="bkmrk-"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou ov"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 617px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 1100w, https://miro.medium.com/v2/resize:fit:1234/format:webp/1*exq_SLtABn5DvSMw9SMXVQ.png 1234w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 617px" srcset="https://miro.medium.com/v2/resize:fit:640/1*exq_SLtABn5DvSMw9SMXVQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*exq_SLtABn5DvSMw9SMXVQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*exq_SLtABn5DvSMw9SMXVQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*exq_SLtABn5DvSMw9SMXVQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*exq_SLtABn5DvSMw9SMXVQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*exq_SLtABn5DvSMw9SMXVQ.png 1100w, https://miro.medium.com/v2/resize:fit:1234/1*exq_SLtABn5DvSMw9SMXVQ.png 1234w">![](https://miro.medium.com/v2/resize:fit:617/1*exq_SLtABn5DvSMw9SMXVQ.png)</source></source></picture></div></figure></div></div></div>This script will do a loop over all the cubes and trigger a coroutine that will rotate them. Setting this function to run when a button is pressed and we have the following effect.

<div class="go gp ga gq gr" id="bkmrk--1"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="pe pf ec pg bg ph" role="button" tabindex="0"><div class="ot ou pd"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*guoYuI-JBiMKQ3nZKJqPzw.gif 1400w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*guoYuI-JBiMKQ3nZKJqPzw.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*guoYuI-JBiMKQ3nZKJqPzw.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*guoYuI-JBiMKQ3nZKJqPzw.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*guoYuI-JBiMKQ3nZKJqPzw.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*guoYuI-JBiMKQ3nZKJqPzw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*guoYuI-JBiMKQ3nZKJqPzw.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/1*guoYuI-JBiMKQ3nZKJqPzw.gif 1400w">![](https://miro.medium.com/v2/resize:fit:700/1*guoYuI-JBiMKQ3nZKJqPzw.gif)</source></source></picture></div></div></figure></div></div></div>####  

#### The Async Way

To convert the current method we are going to swap **IEnumerator** to **async** and then change the *yield* to an *await task*.

<div class="go gp ga gq gr" id="bkmrk--2"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou pj"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 595px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 1100w, https://miro.medium.com/v2/resize:fit:1190/format:webp/1*08xKFYuSP50WZJ2eKjh44Q.gif 1190w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 595px" srcset="https://miro.medium.com/v2/resize:fit:640/1*08xKFYuSP50WZJ2eKjh44Q.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*08xKFYuSP50WZJ2eKjh44Q.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*08xKFYuSP50WZJ2eKjh44Q.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*08xKFYuSP50WZJ2eKjh44Q.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*08xKFYuSP50WZJ2eKjh44Q.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*08xKFYuSP50WZJ2eKjh44Q.gif 1100w, https://miro.medium.com/v2/resize:fit:1190/1*08xKFYuSP50WZJ2eKjh44Q.gif 1190w">![](https://miro.medium.com/v2/resize:fit:595/1*08xKFYuSP50WZJ2eKjh44Q.gif)</source></source></picture></div></figure></div></div></div>With the proper using statement, we can simplify the naming and finish with the following code.

<div class="go gp ga gq gr" id="bkmrk--3"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou pk"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 625px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 1100w, https://miro.medium.com/v2/resize:fit:1250/format:webp/1*QzM1THui6JsoXC-8ATAgGg.png 1250w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 625px" srcset="https://miro.medium.com/v2/resize:fit:640/1*QzM1THui6JsoXC-8ATAgGg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*QzM1THui6JsoXC-8ATAgGg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*QzM1THui6JsoXC-8ATAgGg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*QzM1THui6JsoXC-8ATAgGg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*QzM1THui6JsoXC-8ATAgGg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*QzM1THui6JsoXC-8ATAgGg.png 1100w, https://miro.medium.com/v2/resize:fit:1250/1*QzM1THui6JsoXC-8ATAgGg.png 1250w">![](https://miro.medium.com/v2/resize:fit:625/1*QzM1THui6JsoXC-8ATAgGg.png)</source></source></picture></div></figure></div></div></div>Get ready for the results! They are … exactly the same.

<div class="go gp ga gq gr" id="bkmrk--4"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou pl"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 647px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 1100w, https://miro.medium.com/v2/resize:fit:1294/format:webp/1*erVojNXBzHzxLjm9pH3ZiA.gif 1294w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 647px" srcset="https://miro.medium.com/v2/resize:fit:640/1*erVojNXBzHzxLjm9pH3ZiA.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*erVojNXBzHzxLjm9pH3ZiA.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*erVojNXBzHzxLjm9pH3ZiA.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*erVojNXBzHzxLjm9pH3ZiA.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*erVojNXBzHzxLjm9pH3ZiA.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*erVojNXBzHzxLjm9pH3ZiA.gif 1100w, https://miro.medium.com/v2/resize:fit:1294/1*erVojNXBzHzxLjm9pH3ZiA.gif 1294w">![](https://miro.medium.com/v2/resize:fit:647/1*erVojNXBzHzxLjm9pH3ZiA.gif)</source></source></picture></div></figure></div></div></div><div class="ab ca pm pn po pp" id="bkmrk--5" role="separator">  
</div>Okay so where is the power in this? The benefits are immense. The very first we may be able to see was that I had to add a return type when converting the function from a coroutine to an async method. Coroutines don’t return values like that.

To get around this shortcoming, I’ve had to do crazy things like this before.

<div class="go gp ga gq gr" id="bkmrk--6"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="pe pf ec pg bg ph" role="button" tabindex="0"><div class="ot ou pu"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*cV-zdIf0EfkUs0bSInHchw.png 1400w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*cV-zdIf0EfkUs0bSInHchw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*cV-zdIf0EfkUs0bSInHchw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*cV-zdIf0EfkUs0bSInHchw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*cV-zdIf0EfkUs0bSInHchw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*cV-zdIf0EfkUs0bSInHchw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*cV-zdIf0EfkUs0bSInHchw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*cV-zdIf0EfkUs0bSInHchw.png 1400w">![](https://miro.medium.com/v2/resize:fit:700/1*cV-zdIf0EfkUs0bSInHchw.png)</source></source></picture></div></div></figure></div></div></div>Ugh, yuck. Who wants to read that? With async, everything is far more readable and easier when it comes to return values.

The strongest immediate benefit of async is the power of multithreading. Coroutines run on what is called the **main thread**. The longer it takes the main thread to move, the more lag your application will experience. Async, however, can run on threads besides the main thread. This benefit from async can give a major benefit to an applications performance.

Multithreading is not totally noticeable in this example, but this next benefit is. Async has the ability to run sequentially using the keyword **await**.

But if Coroutines are made for sequential logic, then how is this a benefit? Coroutines *are* made for sequential logic, but they are not made for sequentially executing coroutines.

Now, there are ways to sequentially execute coroutines. The absolute simplest way would be to have a **StartCoroutine()** function at the end of a coroutine. This chaining however, will lead to very difficult code to unpick when it comes time to refactor. A cleaner way to handle this with async methods is using **await.**

Our first step is to change the return type, from **void** to **Task**. Then we can use the await functionality by making the original function also async.

<div class="go gp ga gq gr" id="bkmrk--7"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="pe pf ec pg bg ph" role="button" tabindex="0"><div class="ot ou pv"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 630px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1260/format:webp/1*raFOqRx98mCE9DqDC_cymQ.gif 1260w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 630px" srcset="https://miro.medium.com/v2/resize:fit:640/1*raFOqRx98mCE9DqDC_cymQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*raFOqRx98mCE9DqDC_cymQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*raFOqRx98mCE9DqDC_cymQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*raFOqRx98mCE9DqDC_cymQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*raFOqRx98mCE9DqDC_cymQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*raFOqRx98mCE9DqDC_cymQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1260/1*raFOqRx98mCE9DqDC_cymQ.gif 1260w">![](https://miro.medium.com/v2/resize:fit:630/1*raFOqRx98mCE9DqDC_cymQ.gif)</source></source></picture></div></div></figure></div></div></div>Now when we test this logic, we will see the cubes only rotate after the one before it is finished.

<div class="go gp ga gq gr" id="bkmrk--8"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou pw"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 688px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 1100w, https://miro.medium.com/v2/resize:fit:1376/format:webp/1*jYW2yjojQMcrJVfQU1fqpw.gif 1376w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 688px" srcset="https://miro.medium.com/v2/resize:fit:640/1*jYW2yjojQMcrJVfQU1fqpw.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*jYW2yjojQMcrJVfQU1fqpw.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*jYW2yjojQMcrJVfQU1fqpw.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*jYW2yjojQMcrJVfQU1fqpw.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*jYW2yjojQMcrJVfQU1fqpw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*jYW2yjojQMcrJVfQU1fqpw.gif 1100w, https://miro.medium.com/v2/resize:fit:1376/1*jYW2yjojQMcrJVfQU1fqpw.gif 1376w">![](https://miro.medium.com/v2/resize:fit:688/1*jYW2yjojQMcrJVfQU1fqpw.gif)</source></source></picture></div></figure></div></div></div>Another benefit, that might convince you to never use coroutines again, is that with async, you can make logic wait until a series of tasks have completed.

To demonstrate this, I’m going to create a simple array of colors, then have the button change ONLY after all the cubes have finished moving.

<div class="go gp ga gq gr" id="bkmrk--9"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou px"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 620px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 1100w, https://miro.medium.com/v2/resize:fit:1240/format:webp/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 1240w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 620px" srcset="https://miro.medium.com/v2/resize:fit:640/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 1100w, https://miro.medium.com/v2/resize:fit:1240/1*c7Ri-gF9HpPNsI4bh5kfiQ.png 1240w">![](https://miro.medium.com/v2/resize:fit:620/1*c7Ri-gF9HpPNsI4bh5kfiQ.png)</source></source></picture></div></figure></div></div></div>Before we change this logic, let’s see what we have currently.

<div class="go gp ga gq gr" id="bkmrk--10"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou py"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 697px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1394/format:webp/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 1394w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 697px" srcset="https://miro.medium.com/v2/resize:fit:640/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1394/1*pJbPIMz1s0MS_AMQj-LBwQ.gif 1394w">![](https://miro.medium.com/v2/resize:fit:697/1*pJbPIMz1s0MS_AMQj-LBwQ.gif)</source></source></picture></div></figure></div></div></div>Okay, so now with async, we will be able to change the behavior around so that all the cubes will rotate at the same time, but the button will still only change after they are all finished.

We are going to want to create a list of tasks that we can add to, then check to see if all those tasks have finished before changing the color of the button.

<div class="go gp ga gq gr" id="bkmrk--11"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou pz"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 611px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1222/format:webp/1*XbPp4x9-9RjKBltlRG1QRQ.gif 1222w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 611px" srcset="https://miro.medium.com/v2/resize:fit:640/1*XbPp4x9-9RjKBltlRG1QRQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*XbPp4x9-9RjKBltlRG1QRQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*XbPp4x9-9RjKBltlRG1QRQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*XbPp4x9-9RjKBltlRG1QRQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*XbPp4x9-9RjKBltlRG1QRQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*XbPp4x9-9RjKBltlRG1QRQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1222/1*XbPp4x9-9RjKBltlRG1QRQ.gif 1222w">![](https://miro.medium.com/v2/resize:fit:611/1*XbPp4x9-9RjKBltlRG1QRQ.gif)</source></source></picture></div></figure></div></div></div>The entire code will now look like the following.

<div class="go gp ga gq gr" id="bkmrk--12"><div class="ab ca"><div class="ch bg eu ev ew ex"><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou qa"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 626px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 1100w, https://miro.medium.com/v2/resize:fit:1252/format:webp/1*09BV8dI5XNttiW7kOLfVJA.png 1252w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 626px" srcset="https://miro.medium.com/v2/resize:fit:640/1*09BV8dI5XNttiW7kOLfVJA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*09BV8dI5XNttiW7kOLfVJA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*09BV8dI5XNttiW7kOLfVJA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*09BV8dI5XNttiW7kOLfVJA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*09BV8dI5XNttiW7kOLfVJA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*09BV8dI5XNttiW7kOLfVJA.png 1100w, https://miro.medium.com/v2/resize:fit:1252/1*09BV8dI5XNttiW7kOLfVJA.png 1252w">![](https://miro.medium.com/v2/resize:fit:626/1*09BV8dI5XNttiW7kOLfVJA.png)</source></source></picture></div></figure><figure class="ow ox oy oz pa pb ot ou paragraph-image"><div class="ot ou qb"><picture><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 693px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 1100w, https://miro.medium.com/v2/resize:fit:1386/format:webp/1*zEShllR9XEwX_JTWqtBh8Q.gif 1386w" type="image/webp"><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 693px" srcset="https://miro.medium.com/v2/resize:fit:640/1*zEShllR9XEwX_JTWqtBh8Q.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*zEShllR9XEwX_JTWqtBh8Q.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*zEShllR9XEwX_JTWqtBh8Q.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*zEShllR9XEwX_JTWqtBh8Q.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*zEShllR9XEwX_JTWqtBh8Q.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*zEShllR9XEwX_JTWqtBh8Q.gif 1100w, https://miro.medium.com/v2/resize:fit:1386/1*zEShllR9XEwX_JTWqtBh8Q.gif 1386w">![](https://miro.medium.com/v2/resize:fit:693/1*zEShllR9XEwX_JTWqtBh8Q.gif)</source></source></picture></div></figure></div></div></div>That’s pretty cool right there.

<div class="ab ca pm pn po pp" id="bkmrk--13" role="separator">  
</div>#### Takeaway

This article has only scratched the surface of the power of asynchronous programming but it has definitely convinced me to make the switch from coroutines to async.