JavaScript延迟对象-在承诺后运行两个异步请求

时间:2018-11-07 00:34:35

标签: javascript jquery-deferred deferred

我有一个包含三个选择选项的菜单。第一个选择是其余两个的驱动程序;他们需要填充第一个菜单项的值。但是,它们是并行的-两者都不相互依赖,因此它们的ajax调用可以并行运行。

我当前的Steup对第一个菜单进行ajax调用,然后使用.then()方法对下一个菜单进行调用,对另一个菜单进行.then()对最后一个菜单进行调用。这不是很有效。我试图弄清楚如何使两个子菜单调用都在一个.then()

下运行
    //Get campus list and build menu
    $.getJSON(apiURL)
    .then( function(campusdata) {
        buildMenu('campus', campusdata);
        return $.getJSON(apiURL + '/colleges/' + $campus.val());
    })

    //Build college menu
    .then(function(collegedata) {
        buildMenu('college', collegedata);
        return $.getJSON(apiURL + '/campus-year-terms/' + $campus.val());
    })

    //Build academic terms submenu
    .then(function(termdata){
       buildMenu('term', termdata);
    })

    .done(function(){
        <other stuff that can really be completeduntil menus are populated>
    })

    .fail(console.log.bind(console));

2 个答案:

答案 0 :(得分:1)

您应该使用Promise.all

$.getJSON(apiURL)
.then( function(campusdata) {
    buildMenu('campus', campusdata);

    // use `Promise.all` to run two parallel ajax calls
    return Promise.all([
        $.getJSON(apiURL + '/colleges/' + $campus.val()),
        $.getJSON(apiURL + '/campus-year-terms/' + $campus.val())
    ]);
})

// result will be an array containing the json data from both calls
.then(function(result) {
    buildMenu('college', result[0]);
    buildMenu('term', result[1]);
})
.done(function(){
    <other stuff that can really be completeduntil menus are populated>
})

.fail(console.log.bind(console));

答案 1 :(得分:0)

看来,您的所有三个getJSON()呼叫都是独立的(除非$campus在某种程度上是第一个buildMenu()的副作用,否则不要互相依赖)。这意味着您可以一次(并行)完成所有操作,收集所有结果并一次构建所有菜单:

Promise.all([
    $.getJSON(apiURL),
    $.getJSON(apiURL + '/colleges/' + $campus.val()),
    $.getJSON(apiURL + '/campus-year-terms/' + $campus.val())
]).then(function([campusData, collegeData, termData]) {
    buildMenu('campus', campusdata);
    buildMenu('college', collegedata);
    buildMenu('term', termdata);
    // other code here after all menus are done
}).catch(function(err) {
    // handle error here
});

或者,如果您希望浏览器支持不包含数组销毁的功能:

Promise.all([
    $.getJSON(apiURL),
    $.getJSON(apiURL + '/colleges/' + $campus.val()),
    $.getJSON(apiURL + '/campus-year-terms/' + $campus.val())
]).then(function(results) {
    buildMenu('campus', results[0]);
    buildMenu('college', results[1]);
    buildMenu('term', results[2]);
    // other code here after all menus are done
}).catch(function(err) {
    // handle error here
});

如果由于某种原因$campus.val()确实依赖于第一个API调用,那么您必须将其更改为:

$.getJSON(apiURL).then(function(campusdata) {
    buildMenu('campus', campusdata);
    return Promise.all([
        $.getJSON(apiURL + '/colleges/' + $campus.val()),
        $.getJSON(apiURL + '/campus-year-terms/' + $campus.val())
    ]).then(function(results) {
        buildMenu('college', results[0]);
        buildMenu('term', results[1]);
        // other code here after all menus are done
    });
 }).catch(function(err) {
        // handle error here
 });