JavaScript 延迟对象 - 运行 Promise 后的两个异步请求
JavaScript Deferred Object - Running Two Asynchonous Request After the Promise
我有一个包含三个 select 选项的菜单。第一个 select 是其余两个的驱动程序;他们需要第一个菜单项的值来填充。但是,它们是并行的——这两者都不相互依赖,因此它们的 ajax 调用可以 运行 并行。
我目前的步骤对第一个菜单进行 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));
你应该使用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));
您的所有三个 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
});
我有一个包含三个 select 选项的菜单。第一个 select 是其余两个的驱动程序;他们需要第一个菜单项的值来填充。但是,它们是并行的——这两者都不相互依赖,因此它们的 ajax 调用可以 运行 并行。
我目前的步骤对第一个菜单进行 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));
你应该使用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));
您的所有三个 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
});