Javascript 如何构造这些嵌套异步请求以在继续之前完成批处理?
我需要做一个主要的AJAX表单提交。然而,在继续从submit开始的主要步骤之前,我想中途执行一系列其他初步表单提交和AJAX请求 下面是想法,但是有很多伪代码。如图所示,我想调用Javascript 如何构造这些嵌套异步请求以在继续之前完成批处理?,javascript,jquery,ajax,jquery-deferred,Javascript,Jquery,Ajax,Jquery Deferred,我需要做一个主要的AJAX表单提交。然而,在继续从submit开始的主要步骤之前,我想中途执行一系列其他初步表单提交和AJAX请求 下面是想法,但是有很多伪代码。如图所示,我想调用ajaxFunction,完成所有任务,然后继续主表单提交: $('#mainform').submit(function(e){ e.preventDefault(); var main = this; var data = $('#section :input', main).serial
ajaxFunction
,完成所有任务,然后继续主表单提交:
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
var mainresult = ajaxFunction('arg1', 'arg2');
alert("All preliminary AJAX done, proceeding...");
if(mainresult){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
function ajaxFunction(param1, param2){
//ajax1
ajaxFetchingFunction1('url1', function(){
//ajax2
ajaxFetchingFunction2('url2', function(){
//submit handler
$('#anotherform').submit(function(){
if(someparam === 1){
return true;
}else{
return false;
}
});
});
});
}
现在,我知道它不会像预期的那样工作,因为所有的异步嵌套AJAX调用。我得到的是警报(“所有初步AJAX都完成了,正在进行…”)
甚至在ajaxFunction
中的任何AJAX调用之前执行
我相信这正是延迟/承诺概念引入的场景(“回调地狱”),但我一直在努力思考这个问题。如何构造这些不同的AJAX请求,以便代码执行将等待ajaxFunction
完成并返回mainsult
供后续使用
如何构造这些不同的AJAX请求,例如
执行将等待ajaxFunction完成并返回
后续使用的主要结果
你不能也不能。Javascript不会“等待”异步操作完成。相反,将要在异步操作完成后运行的代码移动到回调中,然后在异步操作完成时调用回调。无论是使用普通异步回调还是作为承诺一部分的结构化回调,都是如此
Javascript中的异步编程需要重新思考和重构控制流,以便在异步操作完成后要运行的内容被放入回调函数中,而不仅仅是在下一行代码中按顺序运行。异步操作通过一系列回调按顺序链接。承诺是一种简化这些回调管理的方法,特别是简化错误传播和/或多个异步操作的同步
如果您坚持使用回调,那么您可以通过完成回调来传达
ajaxFunction()
的完成:
function ajaxFunction(param1, param2, doneCallback){
//ajax1
ajaxFetchingFunction1('url1', function(){
//ajax2
ajaxFetchingFunction2('url2', function(){
doneCallback(someResult);
});
});
}
然后,在这里使用它:
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2', function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2').then(function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
注意:我从代码中删除了您的$(“#另一个表单”).submit()
,因为在将重复调用的函数中插入事件处理程序可能是错误的设计(因为它最终会创建多个相同的事件处理程序)。如果你确定这是正确的,你可以把它插回去,但我觉得它错了
这通常是一个使用承诺的好地方,但是您的代码有点抽象,可以准确地向您展示如何使用承诺。我们需要查看
ajaxFetchingFunction1()
和ajaxFetchingFunction2()
的真实代码,以说明如何使用承诺实现这一点,因为这些异步函数需要创建和返回承诺。如果您在它们内部使用jqueryajax,那么这将很容易,因为jQuery已经为ajax调用创建了承诺
如果修改了ajaxFetchingFunction1()
和ajaxFetchingFunction2()
以返回承诺,则可以执行以下操作:
function ajaxFunction(param1, param2){
return ajaxFetchingFunction1('url1').then(function() {
return ajaxFetchingFunction2('url2');
});
}
然后,在这里使用它:
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2', function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2').then(function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
如何构造这些不同的AJAX请求,例如
执行将等待ajaxFunction完成并返回
后续使用的主要结果
你不能也不能。Javascript不会“等待”异步操作完成。相反,将要在异步操作完成后运行的代码移动到回调中,然后在异步操作完成时调用回调。无论是使用普通异步回调还是作为承诺一部分的结构化回调,都是如此
Javascript中的异步编程需要重新思考和重构控制流,以便在异步操作完成后要运行的内容被放入回调函数中,而不仅仅是在下一行代码中按顺序运行。异步操作通过一系列回调按顺序链接。承诺是一种简化这些回调管理的方法,特别是简化错误传播和/或多个异步操作的同步
如果您坚持使用回调,那么您可以通过完成回调来传达
ajaxFunction()
的完成:
function ajaxFunction(param1, param2, doneCallback){
//ajax1
ajaxFetchingFunction1('url1', function(){
//ajax2
ajaxFetchingFunction2('url2', function(){
doneCallback(someResult);
});
});
}
然后,在这里使用它:
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2', function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2').then(function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
注意:我从代码中删除了您的$(“#另一个表单”).submit()
,因为在将重复调用的函数中插入事件处理程序可能是错误的设计(因为它最终会创建多个相同的事件处理程序)。如果你确定这是正确的,你可以把它插回去,但我觉得它错了
这通常是一个使用承诺的好地方,但是您的代码有点抽象,可以准确地向您展示如何使用承诺。我们需要查看
ajaxFetchingFunction1()
和ajaxFetchingFunction2()
的真实代码,以说明如何使用承诺实现这一点,因为这些异步函数需要创建和返回承诺。如果您在它们内部使用jqueryajax,那么这将很容易,因为jQuery已经为ajax调用创建了承诺
如果修改了ajaxFetchingFunction1()
和ajaxFetchingFunction2()
以返回承诺,则可以执行以下操作:
function ajaxFunction(param1, param2){
return ajaxFetchingFunction1('url1').then(function() {
return ajaxFetchingFunction2('url2');
});
}
然后,在这里使用它:
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2', function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
$('#mainform').submit(function(e){
e.preventDefault();
var main = this;
var data = $('#section :input', main).serialize();
//preliminary nested ajax requests
ajaxFunction('arg1', 'arg2').then(function(result) {
// process result here
alert("All preliminary AJAX done, proceeding...");
if(result){
//final ajax
$.post('mainurl', data, function(result){
console.log(result);
});
}else{
//do nothing
}
});
});
承诺使得处理多个ajax请求变得非常简单,但是“部分表单”对GUI设计的影响可能更大。你必须考虑这样的事情:
- 一张表格分为几部分,还是每部分一张表格
- 从一开始就显示所有部分,还是逐步显示
- 以前验证过的锁