php使用ajax是异步,php – jquery ajax调用不是异步的

博客作者遇到的问题是在使用jQuery AJAX调用时,一个长时运行的PHP脚本阻塞了其他AJAX请求。通过分析,发现PHP会话锁导致了这种异步问题。解决方案是避免在长时运行脚本中使用session_start(),改为使用不依赖会话的数据传递方式,确保了其他请求的正常并发执行。
摘要由CSDN通过智能技术生成

我对jQuery实现它的AJAX方法很新鲜.

我有一个简单的设置,访问两个不同的页面,一个需要10秒钟完成(我有一个计时器设置)和一个检查第一页的状态.

这两个函数是progressCheck(),它每秒以最新状态请求其页面,而beginLogin()需要10秒才能加载.我在服务器上的用户对象中设置了一个值,两个页面都通过symfony 1.4访问.

问题是progressCheck()正常工作,直到我单击beginLogin(),然后在beginLogin()完成之前不会进行任何更改.我有两个函数设置为异步运行.我知道这一定很简单,但是我很茫然.

我在运行此页面时运行了Firebug-Net,结果是:

在10秒呼叫的等待期间调用了许多progressCheck(),但Net表示它们在没有任何等待时间的情况下运行了大约200毫秒.

有任何想法吗?

代码如下:

Begin Login

Check Progress

Clear Check

#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;

}

function beginLogin()

{

try

{

var login_url = "http://example.com/home/loginScript";

$.ajax({

url: login_url,

success: function(data){

$("#result_div").append('

'+data+'

');

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('

'+data+'

');

}

});

}

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;

}

UPDATE

以下是两个PHP函数,它们返回两个页面调用的数据

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);

}

解决方法:

我发现了javascript调用挂起的原因.

为了防止用户会话数据发生race condition,PHP会锁定数据,直到出现两种情况之一.

>之前调用的PHP脚本调用session_write_close().

>先前调用的PHP脚本完成处理并隐式调用session_write_close().

遵循不调用session_start()的服务器调用应允许真正的异步调用的逻辑,我创建了一个虚拟PHP页面,它只是吐出一个简单的字符串,并在10秒脚本运行时每隔一秒调用该页面.它跑得很好.

解决方案来自阅读symfony论坛上的this discussion.

标签:php,jquery,asynchronous,race-condition

来源: https://codeday.me/bug/20190730/1579613.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值