douwei8911
douwei8911
2018-08-27 11:25
浏览 82

为什么对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
    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.

    点赞 评论

相关推荐