我被卡住了。这是没有道理的。

下面的代码行调用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()中)。

09-11 17:37