使用jQuery坚持延期

时间:2015-03-21 23:41:46

标签: javascript jquery deferred

我被困住了。这毫无意义。

以下代码行调用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失败。

为什么一个人工作的时候另一个人是相同的,不起作用?

1 个答案:

答案 0 :(得分: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()的一句话。首先,你必须传递一个或多个承诺。没有神奇的力量可以知道你传递的某些异步函数实际上是什么时候完成的。它只知道如何使用promises。其次,除非您尝试协调多个承诺,否则没有理由使用$.when()。如果您只有一个承诺,则可以在承诺本身上使用.then()(就像我在上面的loadMapData()上所做的那样 - 无需将其包含在$.when()