douwei8911 2018-08-27 11:25
浏览 83
已采纳

为什么对Symfony控制器的jQuery AJAX请求是并行处理而不是异步处理?

When posting simple data to a plain PHP script using jQuery $.ajax({...}) multiple requests are handled in parallel. When doing to same with a Symfony 2.8 controller as a target, the request is handled synchronously. Why is this?

Plain HTML and PHP setup

// Plain PHP file: /testscript.php
<?php 
    sleep($_POST['time']);
    echo $_POST['id'];


// Plain HTML file: /testpage.html
<html>
<head>
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
Click here:
<div id='testbtn' style="background-color: #abc">Click</div>

 <script>
    $(document).ready(function() {
        var start = new Date().getTime();
        var count = 1;

        $("#testbtn").click(function() {
            var time = new Date().getTime();
            console.log('Click at '+count+':' + (time - start));

            $.ajax({
                url : '/testscript.php',
                type : "post",
                data : {'time':3, 'id':count},
                async: true,
                context : this,
                success : function(data) {
                    var end = new Date().getTime();
                    console.log('Click Success: ' + data + "  -  " + (end - start));
                }
            });

            count++;
        });


        $.ajax({
            url : '/testscript.php',
            type : "post",
            data : {'time':10, 'id':0},
            async: true,
            context : this,
            success : function(data) {
                var end = new Date().getTime();
                console.log('Auto Success: ' + data + "  -  " + (end - start));
            }
        });

        console.log('Ajax fired');
    });
</script>

</body>
</html>    

Symfony Setup

// Controller Action to handle /sym_testscript.php
public function testScriptAction(Request $request) {
    sleep($request->get('time'));
    return new Response($request->get('id'), Response::HTTP_OK);
}


// Controller Action to handle /sym_testpage.php
public function testPageAction() {
    return $this->render('MyBundle::sym_testpage.html.twig');
}   


// Twig-Template for /sym_testpage.html
...exactly the same HTML code as above. Twig is only used to insert URL
...
$.ajax({
    url : '{{ path('sym_testscript') }}',
    ...

The page /testpage.html calls /testscript.php when being loaded with a sleep-value of 10 seconds. When clicking the Button a few times the page load waterfall looks something like this:

1: ========================================   // initial call of testscript.php
2:     ============                           // testscript.php called by 1 click
3:      ============                          // testscript.php called by 2 click
4:         ============                       // testscript.php called by 3 click

Each click on the Button immediately calls the testscript.php which is then executed in parallel to the initial call and other button calls. So each click-call runs 3 seconds.

When using the Symfony version instead, the waterfall looks like this:

1: ========================================   // initial call of testscript.php
2:     ====================================================                           
3:      ================================================================                          
4:         ============================================================================

Again, each button click immediately calls the /sym_testscript.php. But now the calls are handled one after the other. Thus the total runtime is not 10 seconds but 19 = 10 + 3 + 3 + 3...

When using the sym_testscript.php within the plain HTML file as the target, the result is the same. Thus the problem seems to be within the Symfony controller...

Why is this? Why are the ajax-calls not handled in parallel when using the Symfony solution?

  • 写回答

1条回答 默认 最新

  • doulaobi7988 2018-08-27 14:33
    关注

    As soon as you start a session in php, php will lock it and subsequent requests will have to wait until the session is available again.

    So if your symfony script uses sessions, you can only execute 1 request at a time using that session while the session is open.

    Disabling sessions (if that even is an option...) or closing it when you don't need it any more will allow parallel requests.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog