如何在回调之外声明变量,在回调中修改,然后在外使用修改后的值?[复制]

How to declare variable outside of callback, modify it in the callback, then use modified value outside? [duplicate]

提问人:Andrew 提问时间:5/5/2021 最后编辑:Andrew 更新时间:5/5/2021 访问量:248

问:

我正在寻找一种方法来修改在回调之外声明的变量,然后在定义回调后使用修改后的变量。我的意图反映在代码中:

$('#my_form').submit(function() {
    let my_condition
    let data = $(this).serialize()
    $.ajax({
        method: 'POST',
        url: '/my_url',
        data: data
    })
    .done(function(json_response) {
        if (json_response.my_variable) {
            my_condition = true
        }
        else {
            my_condition = false
        }
    })
    // I'm looking for a way to guarantee `my_condition` is set by the AJAX before the below code is run.
    if (my_condition) {  // I know `my_condition` will be null because this line won't wait for the AJAX to finish and set `my_condition`.
        return true
    }
    else {  // The event handler will always hit this condition.
        return false
    }
})

我知道我可以在检查等待 AJAX 之前添加阻塞睡眠时间。这不是我正在寻找的解决方案。我也知道我可以根据前端的检查进行设置。但是,由于我的用例的特定原因,需要在后端进行处理。最后,我想避免 AJAX 设置 .my_conditionmy_conditiondatadataasync: false

我知道为什么上面的代码不起作用。我的问题是,有没有办法达到预期的结果?我有一种感觉,可能有一个使用 Promise 的解决方案,但我不明白这将如何完成。

编辑 1:具体用例是关于表单提交的。我希望提交处理程序返回 true 或 false,即根据数据的后端处理结果,通过表单的 action 属性(当 my_condition为 true 时)或不同的 (AJAX) 路由(当 my_condition为 false 时)提交。

编辑 2:这确实是 Javascript 的副本 - 根据 ajax 响应停止表单提交 [duplicate]

javascript jquery ajax promise 回调

评论

0赞 jfriend00 5/5/2021
你不能这样编程。ajax 调用是非阻塞和异步的。这意味着您在调用回调之前执行,因此您正在尝试使用该值 BEFORE 已设置。if (my_condition).done()my_condition
0赞 Andrew 5/5/2021
谢谢。是的,正如我所提到的,我知道为什么代码不起作用。我的问题是,是否有一种不同的模式,也许使用Promise,能够达到相同的效果。
0赞 Bergi 5/5/2021
@Andrew 这是不可能的(不使用同步 XHR)。相反,请始终阻止 submit 事件的默认操作,然后在服务器响应为肯定时执行表单。.submit()
0赞 Andrew 5/5/2021
@Bergi 谢谢,我不知道preventDefault。
0赞 Bergi 5/5/2021
@Andrew 这基本上就是 jQuery 事件处理程序的作用return false

答:

2赞 charlietfl 5/5/2021 #1

我怀疑(尽管具体问题尚不清楚)您希望仅在 ajax 中获得有效响应时才提交表单。

如果满足条件,您可以阻止初始提交,然后在完成回调中提交表单。

$('#my_form').submit(function(e) {
    // prevent submit
    e.preventDefault()
    let form = this;
    let data = $(form).serialize()
    $.ajax({
        method: 'POST',
        url: '/my_url',
        data: data
    })
    .done(function(json_response) {
        if (json_response.my_variable) {
           // trigger native submit, will bypass this jQuery submit listener
           form.submit()
        }
        else {
            // do something else
        }
    })
 })  

评论

0赞 jfriend00 5/5/2021
这真的没有意义,因为呼叫已经在提交表单,所以为什么要再次提交。目前尚不清楚OP代码的目的/意图是什么。$.ajax()
0赞 Andrew 5/5/2021
我认为这确实是有道理的。原始代码实际上从未提交表单,因为提交处理程序回调(预期)总是返回 false。AJAX 调用不一定是提交表单。表单的属性的值可能与 完全不同。此解决方案允许根据服务器处理提交数据的结果以不同的方式提交表单。对不起,如果问题不清楚。action/my_url