我尝试在所有ajax调用完成后调用一次函数。下面的$.when
过早被调用,其中包含一系列空白。从之前几次searchRecommendations()
次呼叫成功以来,$.ajax
被多次呼叫。这可能会以某种方式负责吗?
var MAX = 2; //Maximum levels queried
var ARTISTS = []; //Multidimensional array with the number of potential 'artists' i.e. compare Madonna, to Beethoven to Eminem to nth-artist
var RELEVENT_ARTISTS = 2; //Number of relevent artists added to the list for each new artist
var promises = [];
$(function(){
init(0);
})
function init(i){
for(var i; i<1; i++){
console.log('searchArtists for relevant artist '+$('input')[i].value)
var artist = $('input')[i].value;
$.ajax({
url: 'https://api.spotify.com/v1/search',
data: {
q: artist,
type: 'artist'
},
success: function (response) {
console.log(response.artists.href);
searchRecommendations(response.artists.items[0].id, 0)
//nextLevel(0)
}
});
}
//console.log(ARTISTS)
//getMatches(ARTISTS)
}
function searchRecommendations(artist, depth) {
console.log(' ')
console.log('searchRecommendations '+artist+ ' '+ depth )
if(depth == MAX){ return console.log('max reached '+depth) } else {
promises.push(
$.ajax({
url: 'https://api.spotify.com/v1/artists/' + artist + '/related-artists',
data: {
type: 'artist',
},
success: function (response) {
console.log('RESPONSE');
console.log(response)
for(var r=0; r<RELEVENT_ARTISTS; r++){
console.log(response.artists[r].name)
var obj = { 'artist' : response.artists[r].name, 'level':(depth+1)*5 }
ARTISTS.push(obj)
searchRecommendations(response.artists[r].id, depth+1) //Recursion
}
}
})
)
}
}
$.when.apply(undefined, promises).done(function() {
convert_artists_to_nodes_and_links(ARTISTS)
console.log( 'this is being called too soon')
console.log( promises )
})
答案 0 :(得分:1)
好的,对你的代码进行大量重构,但我认为这会做你想做的事 - 抱歉我无法测试它 - 我会尝试慢慢添加注释来解释代码
function init(i) {
// $('input.artist') - as I can't see your HTML, I would recommend adding cclass='artist' to inputs that you want to process
// [].map.call($('input.artist'), function(artist, i) { - iterate through the inputs, calling the function which returns a promise
// artistP will be an array of Promises
var artistsP = [].map.call($('input.artist'), function(artist, i) {
console.log('searchArtists for relevant artist ' + $('input')[i].value)
var artist = $('input')[i].value;
// return the promise returned by $.ajax
return $.ajax({
url: 'https://api.spotify.com/v1/search',
data: {
q: artist,
type: 'artist'
}
})
// the returned promise needs to wait for the promise returned by searchRecommendations
.then(function(response) {
console.log(response.artists.href);
return searchRecommendations(response.artists.items[0].id, 0);
});
});
// wait for the promises to complete and we're done
$.when.apply($, artistsP).done(function() {
convert_artists_to_nodes_and_links(ARTISTS)
});
}
function searchRecommendations(artist, depth) {
console.log('searchRecommendations ' + artist + ' ' + depth)
if (depth == MAX) {
// just return undefined to stop the recursion
return console.log('max reached ' + depth);
} else {
// return a promise
return $.ajax({
url: 'https://api.spotify.com/v1/artists/' + artist + '/related-artists',
data: {
type: 'artist',
}
})
// the promise needs to wait for the recursed artists
.then(function(response) {
// create an array of promises to wait on
var promises = response.artists.map(function(artist) {
console.log(artist.name)
var obj = {
'artist': artist.name,
'level': (depth + 1) * 5
}
ARTISTS.push(obj)
return searchRecommendations(response.artists[r].id, depth + 1) //Recursion
});
// return a promise that waits for all the "sub" requests
return $.when.apply($, promises);
});
}
}