使用jQuery进行多个Ajax请求

10

我对 Javascript / JQuery 的异步特性遇到了问题。

假设以下情况(为了不让它太麻烦,未计算延迟):

在页面上我有三个按钮(A、B、C),每个按钮都会通过一个 ajax 请求将一个商品添加到购物车中。 如果我在服务器端脚本(PHP)中故意延迟 5 秒,并以 1 秒的间隔按下按钮,则希望结果如下:

Request A, 5 seconds
Request B, 6 seconds
Request C, 7 seconds

然而,结果是这样的

Request A, 5 seconds
Request B, 10 seconds
Request C, 15 seconds
这是否意味着请求被排队而不是同时运行?这与异步相反,对吗?我还尝试向URL添加一个随机的get参数,以强制某些唯一性到请求中,但没有成功。
我有点读过这方面的内容。如果避免使用相同的“请求对象(?)”,就不会出现这个问题。在JQuery中是否有可能强制实现这种行为?
这是我正在使用的代码。
 $.ajax(
 {
  url   : strAjaxUrl + '?random=' + Math.floor(Math.random()*9999999999),
  data  : 'ajax=add-to-cart&product=' + product,
  type  : 'GET',
  success  : function(responseData)
  {
   // update ui
  },
  error  : function(responseData)
  {
   // show error
  }
 });

我也尝试了GET和POST,没有区别。

我希望在单击按钮时立即发送请求,而不是在上一个请求完成后再发送。我希望这些请求同时运行,而不是排队运行。


1
你能在这里发布你的JavaScript代码吗?默认情况下,$.ajax 是异步的。 - Jason Jong
你为什么要在服务器上进行延迟?使用 setInterval 在 JS 中很容易实现。 - lonesomeday
1
@lonesomeday,为什么要指出完全无关的事情呢? - Emil
请检查以下内容:https://dev59.com/AXNA5IYBdhLWcg3wmfIa -- 看起来浏览器不会允许超过2个同时请求,但请参考最高评分答案中原作者的评论。 - Jamie Treworgy
你看到我的回答了吗?它与浏览器无关。 - Amir Raminfar
显示剩余10条评论
5个回答

8

好的,这是我会尝试的方法,我认为你需要一个更好的记录时间的方式。我不确定你现在测试时间的方法是什么,但这是一个好方法。

如果你还没有使用过Firefox的Firebug,请获取它。

打开Firebug并转到网络选项卡。确保您启用了它。

当您单击每个按钮时,您应该看到每个请求都进来了。如果您单击每个按钮,您不会看到下一个请求开始,直到上一个请求结束,那么这告诉我javascript中有问题。但是,我猜测每个条的开始应该相隔1秒钟。请这样做并让我们知道您看到了什么。

编辑

我想我找到了您的问题。我猜测您在php中使用sleep函数。 sleep函数使当前会话休眠。如果您打开3个标签,并放置ajax url,则会注意到相同的行为。每个标签需要5、10、15秒才能完成。我尝试搜索并发现其他人也有相同的结果。这可能是因为PHP实际上并不支持多线程。我建议使用不同的框架。


我使用Firebug来记录时间。认为这很明显,我在这方面不是新手。 - Emil
好的,我会测试一下并告诉你。 - Amir Raminfar
1
我认为我找到了你的问题。请阅读我的编辑。这与JavaScript无关,而是与php中会话和休眠的处理方式有关! - Amir Raminfar
2
还有这个可能会有帮助 http://php.net/manual/en/function.session-write-close.php 阅读第一条评论。 - Amir Raminfar

3

显然,使用 PHP 中的 session_write_close() 很容易通过此行为。但是这会轻松开启 DDos 攻击。我在 10 秒钟内通过按住 F5 刷新页面,并很快地瘫痪了我的开发电脑。

案件结案。


Emil,我花了很多时间为你找到了一个解决方案。但是你却写了同样的答案并将其接受为正确答案。你本可以给一些社区成员以荣誉。 - Amir Raminfar
完成了,抱歉伙计。感谢Amir的帮助!我非常感激! :) - Emil

0
据我所了解,在JS的不同作用域下只能执行串行的Parallel ajax调用。似乎在相同的JS范围内,你需要使用相同的“请求对象”进行序列化处理。
因此,我们可以在Stack Overflow上找到两个关于此问题的优秀回答,请查看链接页面中的第二个回答,其中介绍了一个并行查询堆栈对象,这正是您需要的东西。将您的请求添加到此并行堆栈中,它们将真正地并行执行(Stack Overflow是网络上最好的网站 :-) )。 使用jQuery进行并行异步Ajax请求

其他线程中显示的代码是循环和循环中的ajax调用的代码,对吗?我想在每个事件上进行一次ajax调用,使它们“并行”运行而不会发生冲突。 - Emil
第一个示例使用循环,第二个示例提供了一个处理查询队列的对象,您可以使用此对象来满足您的需求。您可能需要使用jQuery.data以一种不受js范围限制的方式存储查询队列。 - regilero
你还是误解了。我想要做以下操作。点击按钮A,发送一个需要5秒钟的ajax请求。在第一次点击后1秒钟,我点击按钮B并发送一个需要5秒钟的ajax请求。在第二次点击后,我点击按钮C并发送一个需要5秒钟的ajax请求。这些请求应该与B同时进行,即在A之后1秒钟,C在B之后1秒钟。它们不应该同时发送。请看这里:http://data.fuskbugg.se/dipdip/_net.png - Emil
至少你已经有了ParallelAjaxExecuter对象的基础。你需要在它上面添加一些功能。它可以并行运行查询,这是第一个要点,然后你想按照你所要求的顺序获取结果,因此这个对象也应该将结果排队,并在前一个完成时解锁它们(但你可能需要处理一些相当复杂的代码来处理失败)。 - regilero
这里不是一个等待队列,而是一个工作队列,用于向ParallelAjaxExecutor分配一些任务,他不会等到请求结束才获取工作队列中的下一个项目并运行它。该队列用于将您的命令发送到处理ajax请求的外部对象,在一个中心点进行处理。 - regilero

0

如果您甚至无法同时触发两个(2)事件,那么它就不依赖于浏览器。 - Emil

0

你不能同时执行它,因为JS由于一个浏览器UI线程而具有虚假的异步操作。但是你可以尝试使用Web Workers,在浏览器UI线程之外执行代码的方法。它们已经在Firefox 3.5、Chrome 3和Safari 4中得到支持。 也许这会提高你的应用程序的可用性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接