Kaskorian
Kaskorian

Reputation: 446

Async function freezes ui

I want to have a loading screen where the current state is displayed while resources are loading in the background. Therefore I use an async function. I don't know much about async in JavaScript but in C# and I want to use it the same way so I just call the function.

Here is the relevant code:

// main.js
async function loadAssets() {
    var loadingInfo = document.getElementById("loading-info");
    loadingInfo.innerHTML = "Loading entity data..."
    entityDB = JSON.parse(FileReader.read("https://my-domain.com/data/entity-db.json"));
    loadingInfo.innerHTML = "Done...";
}

// file_reader.js
class FileReader {
    static read(fileName) {
        try {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", fileName, false);
            xmlhttp.send();

            if (xmlhttp.status == 200)
                return xmlhttp.responseText;

            return null;
        } catch (error) {
            return null;
        }
    }
}

The problem is that I never see the loading text. The UI freezes for 4 seconds and then the text Done is displayed. Am I misunderstanding async in JavaScript?

Upvotes: 0

Views: 1995

Answers (2)

Jeremy Thille
Jeremy Thille

Reputation: 26360

You should use fetch that can be awaited and extract JSON data. Also forcing an asynchronous operation to become synchronous is always a bad idea. You should embrace asynchronism and learn how to work with it, instead of freezing your code execution.

class FileReader {
    static async read(fileName) {
        try {
            const response = await fetch(fileName);
            const data = await response.json();
            return data
        } catch (error) {
            return null;
        }
    }
}


async function loadAssets() {
    const loadingInfo = document.getElementById("loading-info");
    loadingInfo.innerHTML = "Loading entity data..."
    const entityDB = await FileReader.read("https://my-domain.com/data/entity-db.json");
    loadingInfo.innerHTML = "Done...";
}

Upvotes: 1

Quentin
Quentin

Reputation: 943214

The async keyword has two effects:

  • It makes the function return a promise
  • It allows you to use the await keyword inside it to cause it to go to sleep while it waits for a promise to resolve

It doesn't make blocking code run asynchronously.

You have no asynchronous code. Normally XMLHttpRequest does run asynchronously but you passed false as the third argument to open() triggering the deprecated synchronous mode.


If you want to make an HTTP request asynchronously and deal with the results using promises then you can:

Upvotes: 2

Related Questions