我被卡住了。这是没有道理的。
下面的代码行调用loadJSONfile,然后在getJSON解析后设置对dataLoaded的调用。
$.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,并在loadMapData解析后设置对mapDataLoaded的调用:
$.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失败。
为什么当一个相同的另一个不起作用时一个起作用?
最佳答案
loadMapData()
不返回任何内容。它必须返回$.when()
的承诺,就像您在loadJSONfile()
中所做的那样。
但是,我必须说,您正在为承诺使用一些反模式(在不需要时创建新的承诺)。
这是一个固定的loadMapData()
,没有反模式并且返回了promise:
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()
中)。