Ajax jQuery:在$.post调用中,回调直到结束才被处理

Ajax jQuery:在$.post调用中,回调直到结束才被处理,ajax,jquery,Ajax,Jquery,我在循环中有一个$.post函数。它所做的一切就是调用一个php函数来验证输入。如果输入被验证,它将返回“true”(我测试并运行了它)。此时,我使用回调进行一些处理,但它不起作用 例如,如果我在三个项目上循环,回调函数将处理第三个项目三次,而不是每一次 这是我的相关代码: for (step in steps) { var step_name = steps[step]; // grab input value var s

我在循环中有一个$.post函数。它所做的一切就是调用一个php函数来验证输入。如果输入被验证,它将返回“true”(我测试并运行了它)。此时,我使用回调进行一些处理,但它不起作用

例如,如果我在三个项目上循环,回调函数将处理第三个项目三次,而不是每一次

这是我的相关代码:

for (step in steps) {
            var step_name = steps[step];
            // grab input value
            var step_answer = escape($("#" + step_name).val());
            if (step_answer != "") {
                // check to see if answer validates
                console.log(step_name) // THIS SHOWS CORRECT VALUES: 1, 2, and 3
                $.post("utility.php", {
                    utility: "validateAnswer",
                    step: step_name,
                    answer: step_answer
                },
                function(data) {
                    // if validation suceeds..
                    if (data == "true") {
                        console.log(step_name); // THIS SHOWS WRONG VALUES: 3, 3, and 3
                        correct_steps.push(step_name);
                    }
                });
            } 
        }

有什么想法吗?谢谢。

由于
step\u name
post()
调用之外的一个本地参数,因此在异步回调触发之前,它将被修改(修改为3)

您能否尝试在响应上向下传递
步骤名称
?可能作为json对象的一部分,如下所示

function(data) {
    // if validation suceeds..
    // data example: { valid: "true", step: 1 }
    if (data.valid == "true") {
        console.log(data.step);
        correct_steps.push(data.step);
    }
});

这是因为
step\u name
for
循环中声明,并且
for
循环在第一个POST请求完成之前结束。也就是说,当执行
$.post
中的函数时,循环已循环通过且
步骤名称
等于3。这就是异步调用的本质,如果愿意,可以使用
$.ajax
调用并设置
async:false

for (step in steps) {
    var step_name = steps[step];
    // grab input value
    var step_answer = escape($("#" + step_name).val());
    if (step_answer != "") {
        // check to see if answer validates
        console.log(step_name) // THIS SHOWS CORRECT VALUES: 1, 2, and 3
        $.ajax(
            url: "utility.php",
            data: {
                utility: "validateAnswer",
                step: step_name,
                answer: step_answer
            },
            async: false,
            success: function(data) {
                // if validation suceeds..
                if (data == "true") {
                    console.log(step_name); // THIS SHOWS CORRECT VALUES: 1, 2, and 3
                    correct_steps.push(step_name);
                }
           });
       } 
   }
}

尽管没有必要这样做,“utility.php”将获得正确的值,无论您如何操作。从PHP脚本中注销响应以获得正确的结果会更明智。

这是javascript执行闭包的方式存在的问题。基本上,当您在顶层创建变量时(就像您正在做的),它实际上只创建window.step_name,它实际上是一个全局变量,因此该值不会封装在回调中

但是,如果在函数中创建变量,则不会发生这种情况。因此,尝试将代码包装到函数中,看看它是否有效

简单方法:

(function() {
    // code here
})();

如果是这样,您可能需要考虑将代码放在命名函数中,以便以后更容易维护。

或者,您可以只使用jquery的$。每个:

$.each(steps, function() {
    var step_name = this;
    // code from inside loop here
}

我猜您看到的是由于在循环中使用闭包。也许可以试试:

            $.post("utility.php", {
                utility: "validateAnswer",
                step: step_name,
                answer: step_answer
            },
            function(data) {
                // if validation suceeds..
                if (data == "true") {
                    console.log(this.data.step);
                    correct_steps.push(this.data.answer);
                }
            });

在$.post回调中,
这是AJAX请求对象。

我能想到的唯一一件事是,直到循环完成并且step变量增加到3,您的AJAX调用才完成。

他没有理由需要执行异步调用来实现他想要的。这是真的,但那只是为了证明他必须怎样做,才能使步骤名称在同一时间内不会改变。我的意思是“同步”。实际上,我真正的意思是,你的答案完全错了。这与调用是异步的这一事实无关。