Understanding async/await behavior with Promise resolution in JavaScript

I’m working with an async function that wraps an XMLHttpRequest in a Promise and I’m confused about how the await mechanism interacts with Promise resolution.

async function fetchAudioFile(itemId, category, shouldReturn=false){
    
    let audioPromise = new Promise(function (resolve, reject){
        var request = new XMLHttpRequest();
        request.onload = function(){
            if(this.readyState == 4 && this.status == 200){
                if(this.responseText !== "No Data"){
                    fileName = this.responseText;
                    if(shouldReturn == false){
                        sound = new Audio('media/files/audio/' + fileName);
                        sound.play();
                    }else{
                        resolve(fileName);
                    }
                }else{
                    if(shouldReturn){
                        resolve('File Not Found');
                    }
                }
            }
        };

        request.open("GET", "api/fetch_audio.php?itemId=" + itemId + "&category=" + category, true);
        request.send();   
    });

    let response = await audioPromise;

    if(shouldReturn){
        return response;
    }
}

Then I have another function that calls this async function:

function updateElement(itemId, category, element){
    output = fetchAudioFile(itemId, category, true);
    output.then(function(data){
        if(data == "File Not Found"){
            element.classList.remove('fa-play');
        }
    }); 
}

And finally I call it like this:

updateElement(itemId, category, buttons[i]);

I’m confused about how the await keyword works inside the async function. Does it return the resolved value to the calling function? What exactly does the resolve callback do in the Promise constructor? When I comment out the return statement after await, the Promise doesn’t get fulfilled. Can someone explain how these parts work together?

Your Promise constructor is the problem. You’re calling resolve() only when shouldReturn is true and the file exists. But when shouldReturn is false? The Promise never resolves, so await audioPromise hangs forever. You need resolve() in both branches of your shouldReturn check. Your error handling’s broken too - if the request fails or returns anything other than 200, reject() never gets called. I’d restructure this: always resolve the Promise with either the filename or error message, then handle the audio playback after the await based on shouldReturn.

You’re mixing up the logic flow. When you await audioPromise, it waits for resolve() to get called, then puts that resolved value into the response variable. But without a return statement, your async function just returns undefined instead of passing the filename back. That’s why your .then() in updateElement doesn’t get the data it’s expecting.

Your Promise resolution paths are incomplete. When shouldReturn is false, you play the audio but never call resolve() - so the Promise just hangs there forever. The await keyword pauses execution until the Promise settles, so without that resolve call, your function freezes. Think of resolve() as telling await “I’m done, here’s your value.” When you do let response = await audioPromise, response gets whatever you passed to resolve(). For your “No Data” case when shouldReturn is false, you’re not resolving at all. Add resolve() there too, even if you don’t need the return value. Also, your XMLHttpRequest has no error handling - network failures won’t trigger your reject path.