卡在延迟 jQuery

Stuck on deferreds with jQuery

我卡住了。这毫无意义。

下面这行代码调用 loadJSONfile,然后在 getJSON 解析时设置对 dataLoaded 的调用。

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

这是 loadJSON 文件:

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

这是加载地图数据:

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

但是没用。代码立即解决 deferred,这显然会导致 mapDataLoaded 失败。

为什么一个工作正常而另一个工作不工作?

loadMapData() 没有 returning 任何东西。它必须 return 对 $.when() 的承诺才能像您在 loadJSONfile() 中所做的那样完成它的工作。

但是,我必须说,您正在使用一些反模式来实现承诺(在不需要时创建新的承诺)。

这是一个没有反模式和 return 承诺的固定 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() 已经 return 时创建新的承诺,因此您只需使用已经 returned 的承诺.


还有,关于 $.when() 的一句话。首先,你必须传递一个或多个承诺。它没有神奇的力量知道你传递给它的某些异步函数何时实际完成。它只知道如何使用承诺。其次,除非您试图协调多个承诺,否则使用 $.when() 的理由为零。如果你只有一个承诺,你可以只在承诺本身上使用 .then() (就像我在上面的 loadMapData() 上所做的那样 - 没有必要将它包装在 $.when().