Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Promise gets stuck at resolve

I have an async function that I do multiple times (2), but for some reason the promise get stuck at resolve. It executes resolve(), but doesn't do anything.

Here's the function (basically creates a blob from an URL):

function getBlobAt(url, callback) {
console.log("New getBlobAt Call");
return new Promise(function(resolve) {
    console.log("getBlobAt Promise Created");
    window.URL = window.URL || window.webkitURL;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob';
    xhr.onload = function () {
        console.log("getBlobAt promise completed, resolving...");
        var burl = window.URL.createObjectURL(this.response);
        console.log("getBlobAt promise completed, resolving2...");
        resolve(burl);
        console.log("getBlobAt promise completed, resolving3...");
        //window.URL.revokeObjectURL(burl); //DO THIS WHEN LOADING NEW SONG
    };
    console.log("getBlobAt xhr.send() and callback");
    xhr.send();
    callback(xhr);
    //return xhr;
});
}

And here's the task map:

            var taskstrings = [endmp3, albumart];
            var getBlobTasks = taskstrings.map(function (xurl, i) {
                return function () {
                    console.log("Running a getBlobTask");
                    return getBlobAt(xurl, function (xhr) {
                        console.log("getBlobTask callback");
                        if (g == 0) { //First one is always the mp3 link
                            current_xhr = xhr;
                        } else {
                            current_xhr_album = xhr;
                        }
                    }).then(function (res) {
                        console.log("getBlobTask complete - returning!");
                        if (g == 0) { //First one is always the mp3 link
                            current_blob = res;
                        } else {
                            current_blob_album = res;
                        }
                        return res;
                    });
                };
            });

            var q = getBlobTasks[0](); // start the first one
            for (var i = 1; i < getBlobTasks.length; i++) q = q.then(getBlobTasks[i]);
            q.then(function (result) {
                //Both globs have been returned
                console.log("All getBlobTasks completed!");
                setPlayer(current_blob, current_blob_album);
                target.attr('class', 'glyphicon glyphicon-pause');
            });

It gets stuck at the first resolve(). This is the console output:

Running a getBlobTask
New getBlobAt Call
getBlobAt Promise Created
getBlobAt xhr.send() and callback
getBlobTask callback
getBlobAt promise completed, resolving... 
getBlobAt promise completed, resolving2...
getBlobAt promise completed, resolving3...
like image 976
Fabis Avatar asked Feb 14 '23 05:02

Fabis


1 Answers

You have a g variable you check against 0 but you did not define g anywhere.

The reason you did not see this is that native (or jQuery) promises do not automatically track possibly unhandled rejections.

You can check for errors by appending a .catch to the end of the chain and see if anything went wrong.

q.then(function (result) {
    ...
}).catch(function(e){
     console.log(e.message);
     console.log(e.stack);
});

Which would have shown you the issue.

Alternatively, use a stronger library like Bluebird that will alert you in the case of unhandled rejections.

like image 195
Benjamin Gruenbaum Avatar answered Feb 15 '23 17:02

Benjamin Gruenbaum