当前位置: 首页 > 面试题库 >

Javascript:等到ajax请求完成以关闭页面时

汝宏伯
2023-03-14
问题内容

我希望浏览器将页面保持打开状态,直到发送ajax请求为止。这就是我想像的样子

var requestsPending = 0;

window.onbeforeunload = function() {
    showPleaseWaitMessage();
    while(requestsPending > 0);
}

// called before making ajax request, atomic somehow
function ajaxStarted() {
    requestsPending++;
}
// called when ajax finishes, also atomic
function ajaxFinished() {
    requestsPending--;
}

不幸的是,JS不执行多线程。据我了解,回调(ajaxFinished)将永远不会执行,因为浏览器将尝试等待while循环完成以执行它,因此,它将永远循环。

什么是正确的方法?也许有一种方法可以迫使JS评估待办事项列表中的下一件事,然后返回while循环?还是一些与ajax调用“联接”的语法?我正在为我的ajax使用DWR。

谢谢-Max


问题答案:

编辑 根据您在下面的评论,修改后的答案:

如果要阻止直到 先前启动的 请求完成,可以这样:

window.onbeforeunload = function(event) {
    var s;
    event = event || window.event;
    if (requestsPending > 0) {
        s = "Your most recent changes are still being saved. " +
            "If you close the window now, they may not be saved.";
        event.returnValue = s;
        return s;
    }
}

然后,浏览器将提示用户询问他们是要离开页面还是留在页面上,从而将其置于控制之下。如果他们停留在页面上并且在提示出现时请求已完成,则下次他们关闭页面时,它将使他们无需询问即可关闭页面。

请注意,在现代浏览器中,您的消息将不会显示。而是,浏览器将使用通用消息。因此,在现代浏览器上,返回任何非空字符串就足够了。不过,如果您的用户使用的旧浏览器仍会显示该字符串,则您可能需要返回一个有用的字符串(例如上述字符串)。

有关询问用户是否在此处和此处取消关闭事件的更多信息。

旧答案

理想情况下,如果可能,您要 避免 这样做。:-)

如果你无法避免它,它可能使一个Ajax请求 同步
,以阻塞的onbeforeunload过程,直到它完成。我不知道DWR,但我希望它有一个标志来控制请求是否同步。在原始XmlHTTPRequest
API中,这是第三个参数open

req.open('GET', 'http://www.mozilla.org/', false);
                                            ^ false = synchronous

大多数库将具有等效的库。例如,在Prototype中,它asynchronous: false是选项中的标志。

但是同样,如果您可以避免在页面卸载过程中触发Ajax请求,那么我会这样做。建立,传输和完成请求时,会有 明显的
延迟。让服务器使用超时来关闭它要好得多,这要好得多。(这可能是一个相当短的超时;您可以通过在打开页面时定期在页面中使用 异步
Ajax请求来使会话保持活动状态-例如,一分钟一分钟,两分钟后超时。)



 类似资料:
  • 问题内容: 但是我的问题是不对的: 我正在执行许多ajax请求,并将它们保存在数组中: 正如相关问题所表明的那样,$ .when方法 按顺序 接受 一些对象,但是在这里我要 列出它们的清单 。 我在http://api.jquery.com/jQuery.when/#jQuery-when- deferreds中 阅读了文档,但是该方法似乎不支持这种情况(将to 列表传递给函数) 怎么会这样?请帮

  • 问题内容: 我如何让一个函数等到所有jQuery Ajax请求都在另一个函数中完成之后? 简而言之,在执行下一个请求之前,我需要等待所有Ajax请求完成。但是如何? 问题答案: jQuery现在为此目的定义了一个when函数。 它接受任意数量的Deferred对象作为参数,并在它们全部解析后执行一个函数。 这意味着,如果您要发起(例如)四个ajax请求,然后在完成后执行操作,则可以执行以下操作:

  • 问题内容: 我需要等到我所有的ajax函数都完成后,再继续执行。 我的特殊情况是,在提交表单之前,我需要翻译表单中的某些字段。我通过ajax调用将其转换为外部站点。根据表单中的某些值,我需要进行更多或更少的翻译。完成所有翻译后(如果有),我必须使用ajax验证表单,如果表单有效,则提交。 这是我的方法: 首先,我有一个函数发送ajax调用并对接收到的数据进行处理: 然后,当要提交表单时,我将执行以

  • 问题内容: 我有该代码: 它可以很好地上传图像,但是问题是我找不到一种逐一上传图像的方法,我试图将 async 选项 设置为false, 但是它冻结了网络浏览器,直到所有图像都被上传为止,这不是我所需要的。想要,我想以某种方式模拟此 “ async:false” 选项以执行相同的操作,但不冻结Web浏览器。 这该怎么做 ? 问题答案: 您可以创建一个Promise数组,以便在所有Promise都解

  • 问题内容: 我使用AJAX在页面A上显示页面B的内容。 如何在内容显示之前让jQuery等待所有内容加载(文本,图像等)? 当处理AJAX请求时,我使用beforeSend向用户显示加载动画。现在,我想“延长”等待时间,以便在加载所有图像之前加载动画不会消失。 我最初尝试隐藏附加数据,等待所有图像加载,然后显示内容- 内部但事件似乎没有触发。 有任何想法吗? 更新: 更新的代码: 问题答案: 您必

  • 问题内容: 在Bash中,可以通过追加在后台执行命令。如何在Python中完成? 问题答案: 我用。我在模块级别创建一个单例线程池,然后用于启动任务。 该命令给了我一个未来,我可以将它无限期地与其他未来添加到列表中,直到我想收集全部或部分结果为止。 出于所有逻辑和理由,是一个THREAD池而不是一个进程池。 示例(只要安装了请求,就可以在Python 2和3中使用): 这些请求将同时执行,因此运行