如何从具有多个ajax请求的函数返回正确的值?[复制]

How can I return correct value from function with multiple ajax requests? [duplicate]

提问人:Alper Uluses 提问时间:6/8/2023 更新时间:6/8/2023 访问量:48

问:

我有一个函数,它嵌套了两个ajax调用。当ajax调用成功时,我想从第二个ajax调用中返回一个值。我认为是因为函数结束但ajaxs调用仍然没有结束。但我没有解决它。

我准备了一个示例代码:

        
    var patato = function(){
            $.ajax({
                type: 'POST',
                url: 'https://jsonplaceholder.typicode.com/posts',
                dataType: 'json',
                data: {
                    title: 'foo',
                    body: 'bar',
                    userId: 1,
                },
                success:function(res){
                    console.log("Work 1")
                    $.ajax({
                        type: 'POST',
                        url: 'https://jsonplaceholder.typicode.com/posts',
                        dataType: 'json',
                        data: {
                            title: 'foo',
                            body: 'bar',
                            userId: 1,
                        },
                        success:function(res){
                            console.log("Work 2")
                            return true;
                        }
                    })
                }
            })
            console.log("Çalıştı 3")
        }
        var patatos = patato();
        if(patatos) {
            console.log("Patato true")
        }else{
            console.log("Patato false")
        }
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

JavaScript jQuery Ajax 异步

评论

2赞 Chris G 6/8/2023
Ajax 请求是异步的,这意味着不能保证请求后面的代码行在请求完成后运行

答:

3赞 Alexander Nenashev 6/8/2023 #1

你的函数应该返回一个承诺,因为你正在做一些异步工作(获取)。

此外,我强烈建议使用它来简化逻辑并提高可读性/可维护性:async/await

async function patato() {

    console.log("Çalıştı 3")

    const res = await $.ajax({
        type: 'POST',
        url: 'https://jsonplaceholder.typicode.com/posts',
        dataType: 'json',
        data: {
            title: 'foo',
            body: 'bar',
            userId: 1,
        }
    });

    console.log("Work 1")

    //use res if needed...

    const res2 = await $.ajax({
        type: 'POST',
        url: 'https://jsonplaceholder.typicode.com/posts',
        dataType: 'json',
        data: {
            title: 'foo',
            body: 'bar',
            userId: 1,
        },
    });

    console.log("Work 2")

    //use res2 if needed...

    return true;

}

patato().then(patato => console.log(`Patato ${patato}`));
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

评论

0赞 Alper Uluses 6/8/2023
谢谢,这对我帮助很大。我现在明白了。
0赞 Alexander Nenashev 6/8/2023
@AlperUluses不客气。如果它对你有帮助,你可以投票(向上箭头)并接受我的答案(复选框),这样我将来就会有动力帮助你
1赞 Nick 6/8/2023 #2

我想提到的第一件事是,如果第二个请求不需要第一个请求的响应,那么发出顺序请求就没有多大意义。在这一点上,我假设您有一个用例,需要一个接一个地执行两个 API 调用。

在这里,您有两个选择:使用回调或语法。 在这里,您可以找到两者用法的一个很好的示例: 如何使用 async/await 返回 Ajax 结果?async/await

对于您的特定示例,以下是使用回调执行此操作的方法:

        
    const patato = function(){
            return $.ajax({
                type: 'POST',
                url: 'https://jsonplaceholder.typicode.com/posts',
                dataType: 'json',
                data: {
                    title: 'foo',
                    body: 'bar',
                    userId: 1,
                }
            }).then(function(res1){ 
                console.log("Work 1")
                    return $.ajax({
                        type: 'POST',
                        url: 'https://jsonplaceholder.typicode.com/posts',
                        dataType: 'json',
                        data: {
                            title: 'foo',
                            body: 'bar',
                            userId: 1,
                        }
                    }).then(function(res2){
                        console.log("Work 2")
                        return res1 && res2;
                    })
            })
        }
        patato().then(patatos => {
          if(patatos) {
              console.log(patatos)
          }else {
              console.log("Patato false")
          }
        })
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

或者您也可以使用语法(IMO 这比回调更容易遵循):async/await

   

    const patato = async function(){
            console.log("Work 1");
            const res1 = await $.ajax({
                type: 'POST',
                url: 'https://jsonplaceholder.typicode.com/posts',
                dataType: 'json',
                data: {
                    title: 'foo',
                    body: 'bar',
                    userId: 1,
                }
            });

            console.log("Work 2");
            const res2 = await $.ajax({
                type: 'POST',
                url: 'https://jsonplaceholder.typicode.com/posts',
                dataType: 'json',
                data: {
                    title: 'foo',
                    body: 'bar',
                    userId: 1,
                }
            });
            return res1 && res2;

        }
        async function test() {
            let result = await patato();
            console.log(result);
        }
        test();
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

2赞 Carsten Massmann 6/8/2023 #3

如果第二个作业不需要第一个作业的输出,也可以并行运行两个 AJAX 作业:

async function patato() {

    console.log("Çalıştı 3")
    await $.when( $.ajax({type:'POST',url: 'https://jsonplaceholder.typicode.com/posts',
                         dataType:'json',data: {title: 'foo1',body: 'bar1',userId: 1}}),
                  $.ajax({type: 'POST',url: 'https://jsonplaceholder.typicode.com/posts',
                         dataType:'json',data: {title: 'foo2',body: 'bar2',userId: 2}})
    ).done(function([r1],[r2]){console.log("Both AJAX jobs are finished.",r1,r2)})
    console.log("End of patato.");
    return true;
}

patato().then(pa => console.log(`Patato returns ${pa}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>