我有一个异步功能,我多次(2),但由于某种原因,承诺陷入决心。它执行resolve(),但不执行任何操作。
这是函数(基本上是从URL创建一个blob):
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;
});
}
这是任务图:
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');
});
它停留在第一个resolve()。这是控制台输出:
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...
答案 0 :(得分:6)
您有一个g
变量,您针对0
进行了检查,但未在任何地方定义g
。
您没有看到这一点的原因是本机(或jQuery)承诺不会自动跟踪可能未处理的拒绝。
您可以通过将.catch
附加到链的末尾并查看是否出现任何问题来检查错误。
q.then(function (result) {
...
}).catch(function(e){
console.log(e.message);
console.log(e.stack);
});
哪个会告诉你这个问题。
或者,使用像Bluebird这样更强大的库,在未处理的拒绝情况下会提醒您。
答案 1 :(得分:1)
Derp,看起来变量g出现了无处不在。当我把它改成i时,它就开始工作了。但是为什么我在控制台中没有收到错误?承诺会以某种方式抑制错误吗?
答案 2 :(得分:0)
您遇到了吞噬异常问题。
接受答案中提议的catch
实际上与执行then(null, fn)
相同,它也是转换功能,可以吞下最终的异常(因此不能解决您的问题)。
如果您只想处理该值,最简洁的方法是通过done
(不会误吞吞误)
q.done(function (result) {
// Process the result
});
但是请注意,本机承诺不提供done
,并且因为没有提出错误吞咽的解决方案,所以最好不要使用原生承诺(直到问题解决了) )并使用一个流行的JS库(大多数提供done
)。
另见: