Javascript 等待所有ajax调用完成时,无法使用$。当

Javascript 等待所有ajax调用完成时,无法使用$。当,javascript,jquery,ajax,promise,.when,Javascript,Jquery,Ajax,Promise,.when,我尝试在所有ajax调用完成后调用一次函数。下面的$。当被调用得太快且承诺数组为空时SearchRecommensions()被调用了好几次,之前的几次$.ajax调用成功。这会有什么原因吗 var MAX = 2; //Maximum levels queried var ARTISTS = []; //Multidimensional array with the number of potential 'artists' i.e. compare Madonna, to Beethove

我尝试在所有ajax调用完成后调用一次函数。下面的
$。当
被调用得太快且承诺数组为空时
SearchRecommensions()
被调用了好几次,之前的几次
$.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 )
})
var MAX=2//查询的最大级别
var=[]//具有潜在“艺术家”数量的多维数组,即比较麦当娜、贝多芬、埃米纳姆和第N位艺术家
var Relevant_=2//为每个新艺术家添加到列表中的相关艺术家数量
var承诺=[];
$(函数(){
init(0);
})
函数init(i){

对于(var i;i好的,对代码进行大的重构,但我认为这将满足您的需要-抱歉,我无法测试它-我将尝试慢慢添加注释来解释代码

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);
        });
    }
}

在哪里调用了
SearchRecommensions
?在哪里定义了
MAX
Artisters
?为什么要尝试从
SearchRecommensions
返回
setTimeout
?您可以尝试
.ajaxStop()
它等待所有Ajax调用完成。下面是文档说明:您拥有的代码将在一个空的
数组中等待,
承诺
数组…如果以后通过某种方式调用该函数,
$。当
没有“重新运行”时神奇的是…承诺不能代替事件驱动code@guest271314即使没有setTimeout,我也有这个问题。好吧……那你为什么认为
$。当执行之前,
将等待
init
完成时?…你的代码就像有
var承诺=[]
紧接着是
$。当…
然后是你的函数定义…正如我前面所说,
$。当
不检查承诺中是否有数据时…它怎么知道什么时候添加了所有数据?我得到了
jQuery。延迟异常:#不是函数类型错误:#不是函数
是的,有点需要修正-我搞砸了一点谢谢。它很有效。我会深入研究,找出确切的原因。