If you've done much JavaScript, you've run into the .done() and .then() callback functions, where your code is executed AFTER an asynchronous call completes.

Here, myFunction(myParams) calls makeXhrCall(myParams), an asynchronous XHR API call (the most common type of asynchronous call you will run into). The .then() function waits for the XHR call to complete. When it does, the XHR call returns data, which is used inside the .then() function to call another function, doSomething(data). The result of the doSomething(data) call gets returned out to whoever called the outer function when it's done.

myFunction(myParams) {
    return makeXhrCall(myParams)
        .then(data =>
            doSomething(data)
        );
}

The key thing is, you are using .then() as a hook to do more work when the asynchronous call completes.

For a while now, you've been able to use async/await syntax as a way to treat asynchronous functions as synchronous, meaning no code AFTER the XHR call executes until the line with the await has completed executing.

If you are new to JavaScript, it can be confusing that making asynchronous calls leaves other lines of code UNDER that asynchronous call executing while the asynchronous call is still running. Changing to async/await makes your code clearer because each step is followed in top-down sequence.

async myFunction(myParams) {
    const data = await makeXhrCall(myParams);
    return doSomething(data);
}

The async keyword tells JavaScript, "this code is going to use await at least once". Then you add await right before the asynchronous call. Now the data won't have a value until the XHR completes, and doSomething(data) won't run until the line with the await has finished putting a value in data.