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 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘