Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何构造这些嵌套异步请求以在继续之前完成批处理?_Javascript_Jquery_Ajax_Jquery Deferred - Fatal编程技术网

Javascript 如何构造这些嵌套异步请求以在继续之前完成批处理?

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

我需要做一个主要的AJAX表单提交。然而,在继续从submit开始的主要步骤之前,我想中途执行一系列其他初步表单提交和AJAX请求

下面是想法,但是有很多伪代码。如图所示,我想调用
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设计的影响可能更大。你必须考虑这样的事情:

  • 一张表格分为几部分,还是每部分一张表格
  • 从一开始就显示所有部分,还是逐步显示
  • 以前验证过的锁