jquery - JavaScript Promise gets stuck at resolve - Stack Overflow

I have an async function that I do multiple times (2), but for some reason the promise get stuck at res

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 pleted, resolving...");
        var burl = window.URL.createObjectURL(this.response);
        console.log("getBlobAt promise pleted, resolving2...");
        resolve(burl);
        console.log("getBlobAt promise pleted, 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 plete - 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 pleted!");
                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 pleted, resolving... 
getBlobAt promise pleted, resolving2...
getBlobAt promise pleted, resolving3...

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 pleted, resolving...");
        var burl = window.URL.createObjectURL(this.response);
        console.log("getBlobAt promise pleted, resolving2...");
        resolve(burl);
        console.log("getBlobAt promise pleted, 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 plete - 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 pleted!");
                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 pleted, resolving... 
getBlobAt promise pleted, resolving2...
getBlobAt promise pleted, resolving3...
Share Improve this question edited Dec 25, 2014 at 11:20 Benjamin Gruenbaum 277k89 gold badges520 silver badges517 bronze badges asked Apr 15, 2014 at 15:46 FabisFabis 2,0723 gold badges23 silver badges42 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7

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.

Derp, looks like the variable g appeared out of nowhere. When I changed it to i, it started working. Why didn't I get an error in the console, though? Do promises suppress errors in some way?

You've run into swallowed exception issue.

Proposed catch in accepted answer is actually same as doing then(null, fn), it's also transformation function that will swallow eventual exceptions (so not real solution for your problem).

If you just want to process the value, cleanest way is via done (with no error swallowing implied)

q.done(function (result) {
    // Process the result
});

However mind that native promises do not provide done, and as there's no solution for error swallowing proposed, it's best to not use native promises (until that's solved) and use one of the popular JS libraries instead (most of them provide done).

See also:

  • https://stackoverflow./questions/22294425/promises-ecmascript-6-vs-3rd-party-libraries/22296765#22296765
  • promise.then error swallowing (it's presentation slides, use cursors to move around).

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744247359a4565000.html

相关推荐

  • jquery - JavaScript Promise gets stuck at resolve - Stack Overflow

    I have an async function that I do multiple times (2), but for some reason the promise get stuck at res

    8天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信