2015-03-21 2 views
0

Я застрял. Это не имеет никакого смысла.Застрял на отсрочке с jQuery

Эта следующая строка кода вызывает loadJSONfile, а затем устанавливает вызов dataLoaded при разрешении getJSON.

$.when(loadJSONfile(pathToLoad + "/" + fileToLoad,provIdx)).done(dataLoaded); 

Вот loadJSONfile:

function loadJSONfile(pathToFile,idx1,idx2,num2,idx3,num3,dir) { 

    var deferred = $.Deferred(); 
    //var IDX = idx; 
    /* code to load the stuff goes here */ 
    $.getJSON(pathToFile).done(function(data) { 

     deferred.resolve(data,idx1,idx2,num2,idx3,num3,dir); 
    }).fail(function() { console.log('FAILED') }); 

    return deferred.promise(); 
} 

Следующая строка кода вызывает loadMapData, и устанавливает вызов mapDataLoaded wheen loadMapData решает:

$.when(loadMapData(provinceEntry,regionIdx)).done(mapDataLoaded); 

Вот loadMapData:

function loadMapData(provinceEntry,regionIdx) { 

    var deferred = $.Deferred(); 
    var regionCode = provinceEntry.regions[regionIdx]; 

    $.getJSON('data/topojson' + String(provinceEntry.Number) + String(regionCode) + '.topojson').done(function(topoData) { 

     deferred.resolve(topoData,provinceEntry,regionIdx); 
    }) 
} 

Но это не работает. Код мгновенно отменяет отложенное, что, очевидно, приводит к сбою mapDataLoaded.

Почему одно работает, когда другое, что идентично, не работает?

+3

Может быть, мне что-то не хватает, но они не являются идентично, потому что ваша первая функция возвращает обещание, а ваша вторая функция ничего не возвращает. – Gareth

+1

^'loadMapData' не возвращает обещание – adeneo

+1

И вам не нужно' $ .Deferred' здесь, просто выполните 'return $ .getJSON (...) ', поскольку он уже возвращает обещание. – adeneo

ответ

1

loadMapData() ничего не возвращает. Он должен вернуть обещание для $.when(), чтобы выполнить свою работу, как вы делаете в loadJSONfile().

Но, я должен сказать, вы используете некоторые анти-шаблоны для обещаний (создавая новые обещания, когда вам это не нужно).

Вот неподвижная loadMapData() без анти-паттернов и возвращение обещания:

function loadMapData(provinceEntry,regionIdx) { 
    var regionCode = provinceEntry.regions[regionIdx]; 
    return $.getJSON('data/topojson' + provinceEntry.Number + regionCode + '.topojson'); 
} 

loadMapData(provinceEntry,regionIdx).then(function(topoData) { 
    // you can refer to topoData, provinceEntry and regionIdx here 
    mapDataLoaded(topoData, provinceEntry,regionIdx); 
}, function(err) { 
    // error handling here 
}); 

Ключа к избегая антишаблон, чтобы избежать создания нового обещания, когда $.getJSON() уже возвращает один, так что вы просто использовать обещание, которое уже возвращается.


И слово около $.when(). Во-первых, вы ДОЛЖНЫ передать ему одно или несколько обещаний. У него нет волшебной силы знать, когда какая-то функция асинхронного управления, которую вы передаете, на самом деле выполняется. Он знает, как использовать обещания. И, во-вторых, нет нулевой причины использовать $.when(), если вы не пытаетесь согласовать более одного обещания. Если у вас есть только одно обещание, вы можете просто использовать .then() на самом обещании (как я сделал на loadMapData() выше - нет необходимости обертывать его в $.when().

+0

Хотел бы я ответить на этот ответ 50 раз, потому что Это здорово. Причина так называемого анти-шаблонного подхода заключается в том, что я обнаружил, что мне нужно было замедлить доступ к данным, чтобы избежать смехотворного количества запросов, происходящих практически одновременно. Набор данных разбит примерно на 60 000 небольших файлов JSON, поэтому мне нужно было настроить его, чтобы он не запрашивал следующий, пока первый не загрузился, или это не приведет к тому, что сервер будет ругаться. (Я пытался).Таким образом, используя подход с вложенными обещаниями - триггеры загрузки данных загружают следующий. –

+0

Однако с момента внедрения шаблона проектирования, основанного на загрузке данных, я обнаружил, что потребовалось 15-20 минут, чтобы загрузить все, что явно сумасшедшее, поэтому я все-таки переупакую подход. Тем не менее, мне нравится идея load-data -> load-topojson -> display on map -> получить следующую часть данных. Глазные конфеты. –

Смежные вопросы