如何摆脱挂起的 ajax 调用并加载另一个页面

Posted

技术标签:

【中文标题】如何摆脱挂起的 ajax 调用并加载另一个页面【英文标题】:How to break out of a hanging ajax call and load another page 【发布时间】:2011-07-13 10:12:45 【问题描述】:

我正在开发一个发票应用程序。目前我正在使用 OO php 来构建发票对象。 对象本身包含客户、产品、发票详细信息、公司的对象。

现在我正在制作一个页面以进行概述。发生的问题是,当我有太多发票(仅使用 1500 个虚拟发票进行测试,可能更多)时,php 对象的构建大约需要 7 秒。我觉得这太长了,因为这只是一个请求。此外,由于 php 在服务器端运行,因此在构建对象之前页面没有加载任何内容。 我盯着一个空白屏幕看了 7 秒钟,然后一下子就搞定了一切(都在本地主机上,所以在线应该会更糟)。

由于页面需要更多功能,而不仅仅是概述(即:创建新发票,使用过滤器缩小显示的发票范围),我不希望用户需要等待发票生成在他们可以使用其他功能之前,我改变了页面的工作方式。

现在我首先加载我的基本 html 结构,然后才开始使用 $.ajax() 调用获取我的发票数据。我构建了一个 ajax_loader 来通知用户正在发生的事情。通话完成后会显示数据,但我仍然遇到用户无能为力的问题。他可以单击链接/按钮或其他任何东西,但在我的 ajax 调用完成之前它不会“起作用”。通话完成后,一切正常。在有活动调用时单击链接确实会注册“单击”事件,但触发器仅在 ajax 完成时发生。

这个问题与我的 ajax 调用是否同步无关。如果有人对如何克服这个问题有任何建议,我将不胜感激。 我的第一个想法是取消 ajaxcall,但从我读到现在的内容,我怀疑 abort() 函数无法完成工作。

编辑: 做了一些更多的尝试,我注意到在 ajaxcalls 仍在运行时一切正常,除了从我自己的网站(域、服务器或者我应该调用它)加载页面 或执行涉及同一服务器的任何其他 ajaxcall 即:

$("#dummyButton").click(function()  
window.location='http://www.google.com' //works  
window.location='index.php'  //doesn't work  
alert("test"); //works  
console.log("test"); //works    
)

a href='http://www.google.com'  //works  
a href='index.php' //doesnt work 

所以我的猜测是服务器正忙于构建我的发票对象,因此它不会接受新请求。 以下是对这一结论的补充:

   console.log("start slow call");  
    slow = $.ajax(  
        a very slow/heavy call  
        success:function()  
            console.log('end slow call');  
          
    );  
    console.log('start fast call');  
    quick = $.ajax(  
        a very quick/lightweight call  
        success: function()  
            console.log('end fast call');  
          
    );  

当我同时进行这两个呼叫时,快速呼叫将在慢速呼叫完成之前完成:

控制台打印:

start slow call  
start fast call  
end slow call  
end fast call

同时进行这两个操作会使快速调用需要 5 秒(根据萤火虫),当只进行快速调用时,它会在 150 毫秒内完成

在这之前我已经猜到了,多个 ajaxcall 将以并行方式而不是串行方式完成。

abort() function: (having my 2 ajaxcalls as globals so i can abort them);  

$("a[href]").click(function()  
    slow.abort();  
    quick.abort();  
    window.location = "index.php";  
    return false;  
)  

使 ajaxcalls 被中止,但 服务器仍然继续执行来自两个调用的代码,因此它不会接受我转到 index.php 的请求,直到来自 ajaxcalls 的服务器端代码完成. 大约 5 秒后(在头部计数)我的 index.php 将开始加载

因此想到以下问题:

是否有任何可管理的方法来取消服务器正在为该特定客户端运行的所有进程?

其他没有成为根本原因的想法:

我已经调整了我的发票构造函数,将一个布尔值传递给它以确定对象是否需要所有信息,或者只需要基本信息。这使我的 ajaxcall(或更好的特定 ajaxcall 背后的服务器端进程)缩短了大约 3 秒(在 1500 个虚拟发票上)。我可以调整数据库,因此可以在已经开发的东西上调整很多其他东西。或者,因为构建所有发票对象是耗时的部分,我可以用非 OO 的方式来做吗?

这让我有点难过:这是我的第一个真正的 OOP 项目,它易于使用,但在处理大量对象时显然在计算时间上有很多麻烦。

【问题讨论】:

你确定你是异步而不是同步地执行你的 AJAX 调用吗?在异步调用中,您的网页不应像您描述的那样被“冻结”。 是的,我 100% 确定,但我必须指定一些内容。我认为按钮也不起作用,因为正常的“”不起作用。但这种情况并非如此。点击一个链接不起作用,其他似乎做的工作 前段时间我在预加载图像时遇到了这个问题。我认为至少有些浏览器不喜欢在当前页面上的所有连接完成之前移动到新页面。您最好的选择可能是将数据分成块并检查用户是否想要在每个块之间继续前进。 【参考方案1】:

嘿,我刚刚快速阅读了您的问题 - 所以我希望我的回答不会离题。

当您一次调用两个 php 请求并且一个不会在另一个之前完成时,在慢速请求关闭之前,快速请求可能无法启动会话 (session_start())。

如果不再需要,请在开始任何漫长的过程之前尝试closing the session。

【讨论】:

这解决了我目前遇到的所有问题。非常感谢!你真的拯救了我的一天。并且 gratz 你赢得了我的第一次投票 xD 编辑:显然不是因为我需要更多的代表:) 哇;我不怀疑会话会阻止我离开页面的能力,但当我接受你的建议时,当我想离开时,调用 ajax 的页面立即响应更快;无话可问。看似简单但优秀的解决方案! @butterbrot 这可能对我有帮助,但我对这个 jquery ajax 事情很陌生,我的代码中也发生了同样的事情,直到第一个 ajax 调用没有完成,第二个没有完成。是否有任何关于该问题的确切解决方案的示例。我应该在被调用的 php 函数中调用这个 session_write_close() 吗?

以上是关于如何摆脱挂起的 ajax 调用并加载另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

JS异步函数停止页面加载

在 AngularJS 中中止挂起的 ajax 请求

如何刷新另一个页面内的页面?

Href 转到另一个页面并在该页面上加载 ajax

mvc中的异步页面加载

如何设置通过 AJAX 从另一个页面调用的下拉列表的默认值?