我有一个spotify应用程序,并希望等待循环完成。但它只在重新加载我的应用程序一次后才有效。
function matchRecommendations(result) {
var deferreds = new Array();
for ( var i = 0; i < result.length; i++) {
// Async wait
var dfd = $.Deferred();
deferreds.push(dfd.promise());
...
// Wait for search to finish
search.tracks.snapshot(0, 1).done(
function(snapshot) {
// If match was found => create recommendation object
var uri = snapshot._uris[0];
var meta = snapshot._meta[0];
if ($.type(meta) !== "undefined") {
if ($.type(meta.name) === "string") {
console.log(uri);
var rec = new Recommendation(uri, meta,
explanation, score);
RadioView.prototype.addRecommendation(rec);
}
}
// Async task finished
dfd.resolve();
});
}
return deferreds;
}
在这里,我正在调用上述方法,并希望等待它完成。
$.when.apply($, matchRecommendations(result)).done(
function() {
console.log("finished");
RadioView.prototype.render();
});
我看不出问题为什么这不起作用。问题是第一次加载时没有执行“完成”回调。如果我重新加载应用程序它工作得很好 ......延期材料出了什么问题?
答案 0 :(得分:0)
您的代码似乎存在范围问题,这就是为什么可能只有最后一个延迟才会得到解决的原因。我不知道你是如何检查正在执行的done
回调(不是),但是范围问题可能会导致你的问题(除非result.length
碰巧是1)。
您需要为每个延期创建一个新范围:
var deferreds = [];
for (var i = 0; i < result.length; i++) {
(function(dfd) {
deferreds.push(dfd.promise());
search.tracks.snapshot(0, 1).done(function(snapshot) {
...
dfd.resolve();
});
})($.Deferred());
};
如果result
恰好是一个数组,您可以创建一个更易读的代码:
var deferreds = $.map(result, function() {
var dfd = $.Deferred();
search.tracks.snapshot(0, 1).done(...);
return dfd.promise();
});
答案 1 :(得分:0)
这确实是一个古老的熟悉范围问题,matchRecommendations()
中只有一个范围,其for
循环中设置的所有变量都有其最终值,而当该循环退出时没有其他变量。
有很多方法可以解决这个问题,最简单的(因为你已经在使用jQuery)用result
循环遍历jQuery.each()
数组。
代码如下所示:
function matchRecommendations(result) {
var promises = [];
$.each(result, function(i, rslt) {
...
var p = search.tracks.snapshot(0, 1).done(function(snapshot) {
var uri = snapshot._uris[0];
var meta = snapshot._meta[0];
if ($.type(meta) !== "undefined" && $.type(meta.name) === "string") {
console.log(uri);
RadioView.prototype.addRecommendation(new Recommendation(uri, meta, explanation, score));
}
});
promises.push(p);
});
return promises;
}
注意:
search.tracks.snapshot()
会返回一个承诺(至少它似乎可以安全地假设它),所以没有必要创建一个二级Deferred以在级联中解析。for
循环。