jQuery的ajax调用不同步 [英] jquery ajax call not asynchronous

查看:182
本文介绍了jQuery的ajax调用不同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我新鲜jQuery的执行它的AJAX方法。

我有一个简单的设置访问两个不同的页面,其中一个需要10秒才能完成(我有上有一个定时器设置),一个用于检查的第一页的状态。

这两个功能是 progressCheck()这要求其页面每秒的最新状态和 beginLogin()这需要10秒钟加载。我认为这两个网页通过symfony的1.4访问服务器上设置的用户对象的值。

问题是, progressCheck()正常工作,直到我点击 beginLogin(),则没有变化直到发 beginLogin()结束。我有两个功能设置异步运行。我知道这一定是简单的东西搞清楚,但我很茫然。

我跑了Firebug的 - 净运行此页面,其结果是当:

一个数 progressCheck()在等待期间为10秒的呼叫被称为,但净说,他们在〜200毫秒运行,没有任何等待时间。

任何想法?

code如下:

 <按钮的onclick =beginLogin();>开始登录< /按钮>
<按钮的onclick =progressCheck();>检查进度和LT; /按钮>
<按钮的onclick =clearCheck();>清除检查< /按钮>
< BR />
< D​​IV ID =result_div>< / DIV>
< D​​IV ID =progress_div>< / DIV><风格类型=文/ CSS>
    #progress_div
    {
        宽度:800像素;
        高度:200像素;
        边框:1px的固体#CCCCCC;
        溢出:滚动;
        背景色:#AAEEFF;
    }    #result_div
    {
        宽度:800像素;
        高度:300像素;
        边框:1px的固体#CCCCCC;
        溢出:滚动;
        背景色:#FFEEAA;
    }
< /风格>
<脚本类型=文/ JavaScript的>
    功能beginLogin()
    {
        尝试
        {
            VAR LOGIN_URL =htt​​p://example.com/home/loginScript;
            $阿贾克斯({
                网址:LOGIN_URL,
                成功:功能(数据){
                    $(#result_div)追加('< pre>'+数据+'< / pre><小时/>');
                    警报(成品);
                }
            });
        }
        赶上(E)
        {
            警报(有开始登录的错误:+ E);
            返回false;
        }
        返回true;
    }    功能progressCheck()
    {
        尝试
        {
            VAR check_url =htt​​p://example.com/home/checkLoginProgress;
            $阿贾克斯({
                网址:check_url,
                成功:功能(数据){
                    $(#progress_div)追加('< pre>'+数据+'< / pre><小时/>');
                }
            });
        }
        赶上(E)
        {
            警报(有一个错误检查的进展:+ E);
            返回false;
        }
        check_id = setTimeout的('progressCheck()',1000);
        返回true;
    }    //设置进度检查功能调用每一秒
    VAR check_id = setTimeout的('progressCheck()',1000);    功能clearCheck()
    {
        尝试
        {
            clearTimeout(check_id);
        }
        赶上(E)
        {
            警报(发生错误清除检查:+ E);
            返回false;
        }
        返回true;
    }
< / SCRIPT>

更新
下面是返回数据的两个页面调用两个PHP函数

 定义(DEBUG,真正的);公共职能executeCheckLoginProgress(sfWebRequest $要求)
{
    如果(这 - $>的getUser() - > hasAttribute('login_script','sfGuardSecurityUser'))
        $这个 - > login_progress = $这个 - >的getUser() - GT;的getAttribute('login_script',-1,sfGuardSecurityUser');
    其他
        $这个 - > login_progress ='​​[未定义]';
    康涅狄格州$ = $这个 - > connectTestDb();
    $查询= sprintf的(SELECT * FROM WHERE COMPANY_TYPE ID = 1;);
    $结果= mysql_query($查询,$康恩);
    $这个 - > login_progress = mysql_result($结果,0,'名');
    如果($请求 - > isXmlHtt prequest())
    {//这是一个Ajax一切,只返回值
        $这个 - > GETRESPONSE() - GT; setHttpHeader(内容类型,text / plain的);
        $这个 - > GETRESPONSE() - GT; setContent($这个 - > login_progress);
        返回sfView ::无;
    }
}公共职能executeLoginScript(sfWebRequest $要求)
{
    $ USER = $这个 - >的getUser();
    如果($用户可与GT;!hasAttribute('login_script','sfGuardSecurityUser'))
        $用户可与GT;的setAttribute('login_script',0,'sfGuardSecurityUser');    $这 - > login_value = $用户可与GT;的getAttribute('login_script',0,'sfGuardSecurityUser');    康涅狄格州$ = $这个 - > connectTestDb();
    $查询= sprintf的(SELECT * FROM WHERE COMPANY_TYPE ID = 1;);
    $结果= mysql_query($查询,$康恩);
    $这个 - > login_value = mysql_result($结果,0,'名');    $结果= $用户自> assignAccessLevelIds();
    如果($结果===真)
    {
        $这个 - > login_value + = 5;
        $用户可>的setAttribute('login_script',$这个 - > login_value,sfGuardSecurityUser');
        $查询= sprintf的(UPDATE COMPANY_TYPE SET`name` ='%s'的WHERE ID = 1;mysql_real_escape_string($这个 - > login_value));
        $结果= mysql_query($查询,$康恩);
        $这个 - > login_progress = mysql_result($结果,0,'名');
    }
    其他
    {
        ::的DataMan logRawMessage('无法设置访问权限级别的用户['$用户可方式>的getAttribute('USER_ID',NULL,'sfGuardSecurityUser'),sfLogger ::警告);
    }
    //只是用于测试的睡眠!
    如果(DEBUG ===真)
        睡眠(5);    $结果= $用户自> assignCompanyIds();
    如果($结果===真)
    {
        $这个 - > login_value + = 5;
        $用户可>的setAttribute('login_script',$这个 - > login_value,sfGuardSecurityUser');
        $查询= sprintf的(UPDATE COMPANY_TYPE SET`name` ='%s'的WHERE ID = 1;mysql_real_escape_string($这个 - > login_value));
        $结果= mysql_query($查询,$康恩);
        $这个 - > login_progress = mysql_result($结果,0,'名');
    }
    其他
    {
        ::的DataMan logRawMessage('无法设置公司IDS用户['$用户可方式>。的getAttribute('USER_ID',NULL,'sfGuardSecurityUser')']'.__ LINE__,sfLogger ::警告);
    }
    //只是用于测试的睡眠!
    如果(DEBUG ===真)
        睡眠(5);}


解决方案

我已经发现的JavaScript调用挂的原因。

要prevent从用户会话数据中出现的竞争条件,PHP锁定数据,直到两个一出现的情况。


  1. 在previously称为PHP脚本调用 session_write_close()


  2. 在previously称为PHP脚本完成处理和隐式调用 session_write_close()


继到服务器的呼叫不叫在session_start()应该让真正的异步调用逻辑,我创建了刚刚吐出了一个简单的一个虚拟的PHP页面串并呼吁该页面每一秒,而10秒脚本运行。它完美地跑了。

该解决方案从阅读<一来到href=\"http://forum.symfony-project.org/viewtopic.php?f=20&t=22481&p=88958&hilit=asynchronous#p88958\">this在symfony的论坛讨论。

I am fresh to jQuery's implementation of it's AJAX methods.

I have a simple setup that accesses two different pages, one which takes 10 seconds to complete (I have a timer set on it) and one which checks on the status of the first page.

The two functions are progressCheck() which requests its page every second with the latest status and beginLogin() which takes 10 seconds to load. I set a value in the user object on the server that both pages access through symfony 1.4.

The issue is that the progressCheck() works correctly until I click beginLogin(), then no changes are made until beginLogin() finishes. I have both functions setup to run asynchronously. I know it must be something simple to figure out, but I am at a loss.

I ran Firebug - Net while running this page and the result is:

A number of the progressCheck() are called during the wait period for the 10 second call, but Net says they ran in ~200 ms without any wait time.

Any ideas?

Code below:

<button onclick="beginLogin();">Begin Login</button> 
<button onclick="progressCheck();">Check Progress</button> 
<button onclick="clearCheck();">Clear Check</button>
<br/>
<div id="result_div">

</div>
<div id="progress_div">

</div>

<style type="text/css">
    #progress_div
    {
        width:              800px;
        height:             200px;
        border:             1px solid #CCCCCC;
        overflow:           scroll;
        background-color:   #AAEEFF;
    }

    #result_div
    {
        width:              800px;
        height:             300px;
        border:             1px solid #CCCCCC;
        overflow:           scroll;
        background-color:   #FFEEAA;
    }
</style>
<script type="text/javascript">
    function beginLogin()
    {
        try
        {
            var login_url   = "http://example.com/home/loginScript";
            $.ajax({
                url:        login_url,
                success:    function(data){
                    $("#result_div").append('<pre>'+data+'</pre><hr/>');
                    alert("finished");
                }
            });
        }
        catch(e)
        {
            alert("There was an error beginning the login: " + e);
            return false;
        }
        return true;
    }

    function progressCheck()
    {
        try
        {
            var check_url   = "http://example.com/home/checkLoginProgress";
            $.ajax({
                url:        check_url,
                success:    function(data){
                    $("#progress_div").append('<pre>'+data+'</pre><hr/>');
                }
            });
        }
        catch(e)
        {
            alert("There was an error checking the progress: " + e);
            return false;
        }
        check_id = setTimeout('progressCheck()', 1000);
        return true;
    }

    // set progress checking function to call every second
    var check_id = setTimeout('progressCheck()', 1000);

    function clearCheck()
    {
        try
        {
            clearTimeout(check_id);
        }
        catch(e)
        {
            alert("There was an error clearing the check: " + e);
            return false;
        }
        return true;
    }
</script>

UPDATE Here are the two PHP functions that returns the data for the two page calls

define('DEBUG', true);

public function executeCheckLoginProgress(sfWebRequest $request)
{
    if($this->getUser()->hasAttribute('login_script', 'sfGuardSecurityUser'))
        $this->login_progress = $this->getUser()->getAttribute('login_script', -1, 'sfGuardSecurityUser');
    else
        $this->login_progress = '[undefined]';
    $conn = $this->connectTestDb();
    $query  = sprintf("SELECT * FROM company_type WHERE id = 1;");
    $result = mysql_query($query, $conn);
    $this->login_progress = mysql_result($result, 0, 'name');
    if($request->isXmlHttpRequest())
    {   // this is an ajax all, only return value
        $this->getResponse()->setHttpHeader("Content-type", "text/plain");
        $this->getResponse()->setContent($this->login_progress);
        return sfView::NONE;
    }
}

public function executeLoginScript(sfWebRequest $request)
{
    $user = $this->getUser();
    if(!$user->hasAttribute('login_script', 'sfGuardSecurityUser'))
        $user->setAttribute('login_script', 0, 'sfGuardSecurityUser');

    $this->login_value      = $user->getAttribute('login_script', 0, 'sfGuardSecurityUser');

    $conn = $this->connectTestDb();
    $query  = sprintf("SELECT * FROM company_type WHERE id = 1;");
    $result = mysql_query($query, $conn);
    $this->login_value = mysql_result($result, 0, 'name');

    $result = $user->assignAccessLevelIds();
    if($result === true)
    {
        $this->login_value += 5;
        $user->setAttribute('login_script', $this->login_value, 'sfGuardSecurityUser');
        $query  = sprintf("UPDATE company_type SET `name` = '%s' WHERE id = 1;", mysql_real_escape_string($this->login_value));
        $result = mysql_query($query, $conn);
        $this->login_progress = mysql_result($result, 0, 'name');
    }
    else
    {
        DataMan::logRawMessage('Unable to set access level user ['.$user->getAttribute('user_id', null, 'sfGuardSecurityUser'), sfLogger::WARNING);
    }
    // just for testing sleep!
    if(DEBUG === true)
        sleep(5);

    $result = $user->assignCompanyIds();
    if($result === true)
    {
        $this->login_value += 5;
        $user->setAttribute('login_script', $this->login_value, 'sfGuardSecurityUser');
        $query  = sprintf("UPDATE company_type SET `name` = '%s' WHERE id = 1;", mysql_real_escape_string($this->login_value));
        $result = mysql_query($query, $conn);
        $this->login_progress = mysql_result($result, 0, 'name');
    }
    else 
    {
        DataMan::logRawMessage('Unable to set company ids user ['.$user->getAttribute('user_id', null, 'sfGuardSecurityUser').'] '.__LINE__, sfLogger::WARNING);
    }
    // just for testing sleep!
    if(DEBUG === true)
        sleep(5);



}

解决方案

I have discovered the cause of the javascript call hanging.

To prevent a race condition from occurring with user session data, PHP locks the data until one of two conditions occur.

  1. The previously called PHP script calls session_write_close().

  2. The previously called PHP script completes processing and implicitly calls session_write_close().

Following the logic that a call to the server that does not call session_start() should allow true asynchronous calls, I created a dummy PHP page that just spits out a simple string and called to that page every second while the 10 second script ran. It ran perfectly.

The solution came from reading this discussion on the symfony forums.

这篇关于jQuery的ajax调用不同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆