我刚开始使用 $.when
和 $.Deferred()
,但我似乎无法让它们工作
我想做的是运行一些函数,当它们全部完成时触发最终函数
这是我尝试过的几个选项
选项 1 - 返回 d1.getRating 不是一个函数
(这是脚本中进一步的函数),遵循 JQuery 中的文档据我了解他们
// Set Deferred
var d1 = $.Deferred();
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output
$.when(d1).done(function (ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(showCheckIn, traktSlug, ratingValue);
});
// Get Rating
d1.getRating(idResp[0].type, idResp[0].movie.ids.trakt);
}
选项 2 - 返回 ratingValue 未定义
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output
$.when(getRating(idResp[0].type, idResp[0].movie.ids.trakt)).done(function (ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(showCheckIn, traktSlug, ratingValue);
});
}
任何建议或正确方向的插入将不胜感激
完整源代码可以是viewed on GitHub
更新
读完JQuery docs后我意识到再次说明 resolve()
不是通用函数的名称,因此我修改了代码,但仍然得到 ratingValue is undefined
返回
更新了选项 1 代码
// Set Deferred
var d1 = $.Deferred();
// Return movie information
if (idResp[0].type === "movie") {
// Output Slug
var traktSlug = 'movies/' + idResp[0].movie.ids.slug;
// Output Div
$.when(d1).done(function(ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(1, traktSlug, ratingValue);
});
// Get Rating
d1.resolve(getRating(idResp[0].type, idResp[0].movie.ids.trakt));
}
更新2
抱歉,很抱歉没有包含 getRating
函数。如下
// Get Rating
function getRating(type, id, season = 0, episode =0) {
var slugType = "";
switch (type) {
case "movie":
slugType = "movies";
break;
default:
slugType = "movies";
break;
}
var request = new XMLHttpRequest();
request.open('GET', 'https://api.trakt.tv/' + slugType + '/' + id + '/ratings');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('trakt-api-version', '2');
request.setRequestHeader('trakt-api-key', APP_KEY);
request.onreadystatechange = function () {
if (this.readyState === 4) {
// Get Response and put in array
var ratingsResp = JSON.parse(this.responseText);
// Return Rating
return Math.round(ratingsResp.rating * 10);
} else {
return 0;
}
};
request.send();
}
最佳答案
主要要做的是编写getRating()
来返回一个promise。您可以promisify XMLHttpRequest()
,但使用jQuery.ajax()
要容易得多。
这就是,基于original code on GitHub :
function getRating(type, id, season=0, episode=0) { // mmm, formal defaults - odd for browser-based javascript.
var slugType;
switch(type) {
case 'movie':
slugType = 'movies';
break;
default:
slugType = 'movies';
}
return $.ajax({
url: 'https://api.trakt.tv/' + slugType + '/' + id + '/ratings',
headers: {
'Content-Type': 'application/json',
'trakt-api-version': '2',
'trakt-api-key': APP_KEY
},
dataType: 'json'
}).then(function(response) {
return Math.round(response.rating * 10);
}).then(null, function(xhr, textMessage, errorThrown) {
console.error('getRating error: ', textMessage);
return $.when(0); // error recovery.
});
}
然后,在主例程中也使用 jQuery.ajax()
:
chrome.storage.local.get('access_token', function(result) {
var ACC_TOK = result.access_token;
if (ACC_TOK && typeof ACC_TOK !== undefined) {
if (tabURL.includes('imdb.com')) {
$.ajax({
url: 'https://api.trakt.tv/search/imdb/' + tabURL.match(/tt\d{7}/),
headers: {
'Content-Type': 'application/json',
'trakt-api-version': '2',
'trakt-api-key': APP_KEY
},
dataType: 'json'
}).then(function(idResp) {
if(idResp[0].type === 'movie') {
return getRating(idResp[0].type, idResp[0].movie.ids.trakt).then(function(ratingValue) {
console.log('Rating Is: ' + ratingValue);
outputIMDb(1, 'movies/' + idResp[0].movie.ids.slug, ratingValue);
});
} else {
console.log("Type: " + idResp.type);
}
}).fail(function(xhr, textMessage, errorThrown) {
console.error(textMessage);
});
}
}
});
请注意,由于 jQuery.ajax()
返回一个 Promise,因此无需生成/解析您自己的 jQuery.Deferred()
。
上面的代码可能不是 100% 正确,但离工作解决方案应该还有很大的距离。
关于javascript - 使用 JQuery when 和 deferred 仍然返回未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38940881/