【问题标题】:How to make callback run asynchronously?如何使回调异步运行?
【发布时间】:2022-07-27 21:07:13
【问题描述】:

我有一个名为 getAandB 的 JavaScript 函数,它接受回调。 getAandB 首先使用 ajax 获取值“a”。然后它使用值“a”作为参数调用回调。回调获取值 'b' 和 console.logs 'a' 和 'b' 到控制台。所以我在控制台中得到{"key":"a"} {"key":"b"}

我认为这两个 ajax 调用会同时/异步发生。但是,它们似乎一个接一个地运行,即。同步。

ajax 请求的 JavaScript 代码和 PHP 代码如下所示:

index.html:

<script>
    function getAandB(callback){
        const xhr = new XMLHttpRequest();
        xhr.open('GET', './ajax-a.php', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                callback(xhr.responseText)
            }
        }
        xhr.send();
    }

    function callback(resultA){
        const xhr = new XMLHttpRequest();
        xhr.open('GET', './ajax-b.php', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                const resultB = xhr.responseText;
                console.log(resultA, resultB);
            }
        }
        xhr.send();
    }
    getAandB(callback);
</script>

ajax-a.php:

<?php
sleep(5);
$response = [
    "key" => "a",
];
echo json_encode($response);

ajax-b.php 的代码与 ajax-a.php 相同,只是 $response.key 的值是 b 而不是 a。

我认为上面的代码会导致同时进行 ajax 调用以获取 'a' 和 'b'。但是,如果 ajax-a.php 和 ajax-b.php 的 PHP 代码都休眠 5 秒,那么 console.log 需要 10 秒才能出现。如果只有一个 ajax-?.php 脚本休眠 5 秒,则 console.log 需要 5 秒才能出现。

我如何使用回调来组合 ajax 调用的结果,就像我在这里所做的那样,但是让各个调用同时/异步发生?或者,不能用回调来实现吗?

【问题讨论】:

  • 这是因为“会话阻塞”,而不是因为 ajax。如果您在没有会话的情况下尝试它,它将并行工作。 stackoverflow.com/a/15693029/3807365
  • 这与此无关,与您等待xhr.onreadystatechange 显示第一个呼叫甚至在启动第二个呼叫之前已完成这一事实有关
  • 为什么您会期望在 ajax-a 完成之前发生对 ajax-b 的 XHR 调用?在完成ajax-a 之前,您不要致电callback。所以很自然,两个电话接连发生。 (如果你解决了这个问题并且实际上一个接一个地拨打电话,没有等待,你可能会遇到会话阻塞,但现在第二个甚至没有开始,直到第一个完成。)

标签: javascript ajax asynchronous callback


【解决方案1】:

如果您希望 ajax-b 的请求与 ajax-a 的请求大致同时向我发出,那么您需要分别调用xhr.send() 几乎在同一时间。

目前,对 ajax-bsend() 的调用是作为 callback() 的一部分进行的,您只有在收到响应后调用ajax-a 的请求。


然后您需要添加额外的逻辑来确定您何时收到两个响应,以便同时记录这两个数据位(假设您仍然想这样做)。

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 2017-11-21
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2017-09-09
    • 2018-08-22
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多