Javascript范围/提升或承诺/延期?

Javascript范围/提升或承诺/延期?,javascript,jquery,ajax,jquery-deferred,hoisting,Javascript,Jquery,Ajax,Jquery Deferred,Hoisting,我试图在jqueryeach循环中对API进行外部AJAX调用 这是我到目前为止的代码 getStylesInfo(tmpMake, tmpModel, tmpModelYear, tmpSubmodel).done(function(data){ var holder = []; $.each(styles, function(index, value) { var tempValue = value; var temp = getNaviga

我试图在jqueryeach循环中对API进行外部AJAX调用

这是我到目前为止的代码

getStylesInfo(tmpMake, tmpModel, tmpModelYear, tmpSubmodel).done(function(data){
    var holder = [];

    $.each(styles, function(index, value) {
        var tempValue = value;
        var temp = getNavigationInfo(value.id);

        $.when(temp).done(function(){
            if(arguments[0].equipmentCount == 1){
                holder.push(tempValue);
                console.log(holder);
            }
        });
    });
});

console.log(holder);

function getStylesInfo(make, model, year, submodel){
    return $.ajax({
    type: "GET",
    url: apiUrlBase + make + '/' + model + '/' + year + '/' + 'styles?  fmt=json&' + 'submodel=' + submodel + '&api_key=' + edmundsApiKey + '&view=full',
   dataType: "jsonp"
});   


function getNavigationInfo(styleId){
    return $.ajax({
    type: "GET", 
    url: apiUrlBase + 'styles/' + styleId + '/equipment?availability=standard&name=NAVIGATION_SYSTEM&fmt=json&api_key=' + edmundsApiKey,
    dataType: "jsonp"
});   
getStylesInfo()返回与此类似的内容。包含汽车模型信息的对象数组

var sampleReturnedData = [{'drivenWheels': 'front wheel drive', 'id': 234321}, {'drivenWheels': 'front wheel drive', 'id': 994301}, {'drivenWheels': 'rear wheel drive', 'id': 032021}, {'drivenWheels': 'all wheel drive', 'id': 184555}];  
我正在尝试循环sampleReturnedData,并使用getNavigationInfo()函数在不同的AJAX调用中使用每个id作为参数

我想循环查看结果并进行检查。如果这是真的,那么我想把整个对象推到holder数组中

问题是函数外部的console.log(holder)返回一个空数组。if语句中的console.log(holder)工作正常

我不确定这是范围/吊装问题,还是我使用延期的方式存在问题

我读过这个问题,很多人都喜欢它。他们建议使用其中一种

async:false
或者更好地重写代码。我已经多次尝试并使用控制台调试器。我不想把它设为false。我只是不确定到底发生了什么

我也读过一篇关于提升的文章

我相信这与延期有关,但我没有足够的JS知识来解决这个问题

谢谢

我不确定这是范围/吊装问题,还是我使用延期的方式存在问题

事实上,两者都是:

  • holder
    仅在回调函数内声明(作为局部变量),因此它在函数外是
    未定义的
  • console.log
    是在异步回调函数用值填充数组之前执行的,因此即使
    holder
    在作用域中,它仍然是空的。另见
因此,您应该做的确实是重写代码以正确使用承诺:-)


另外,我猜
样式
应该是
数据
中的嵌套对象
getStylesInfo(tmpMake, tmpModel, tmpModelYear, tmpSubmodel).then(function(data) {
    var holder = [];
    var promises = $.map(data.styles, function(value, index) {
        return getNavigationInfo(value.id).then(function(v){
            if (v.equipmentCount == 1)
                holder.push(value);
        });
    });
    return $.when.apply($, promises).then(function() {
        return holder;
    }); // a promise for the `holder` array when all navigation requests are done
}).then(function(holder) {
    console.log(holder); // use the array here, in an async callback
});