在这个编码示例中,函数logout()
不会执行所有的异步调用,并且不会等到它们完成-相反,页面在此之前正在卸载,因为beforeunload
事件的返回触发了卸载页面。
$(window).on('beforeunload', function(event) {
event.preventDefault();
logout();
return;
});
我想尝试的是事件函数在logout()
中的几个异步调用完成后返回。
我尝试了回调,但最终得到了这个,这不是期望的结果,因为它返回回调,而不是事件函数。
$(window).on('beforeunload', function(event) {
event.preventDefault();
logout(function(x) { return; });
});
由于页面上执行的所有内容在页面卸载时都将失效,因此您不能依赖页面本身来完成异步调用。
chrome扩展的一个词是利用背景页。您可以简单地将消息发送到beforeunload
处理程序中的后台页面,捕获您需要处理的所有信息,并在后台页面中执行异步调用。示例代码如下:
content.js
window.addEventListener('beforeunload', function() {
chrome.runtime.sendMessage({ info: "Here is the info you would like to pass to background page"});
});
background.js
chrome.runtime.onMessage.addListener(function(request) {
// The following is your async call
logout();
// Don't forget the following code
return true;
});
不要忘记从后台页面的事件侦听器返回true,因为当事件侦听器返回时chrome.runtime.onMessage.addListener
将无效,详细信息请参见此答案。
尝试使用async/await
作为处理程序,即:
$(window).on('beforeunload', async function(event) {
await logout();
event.preventDefault();
event.returnValue = false; // Seems require this for Chrome
});
当然,您应该从logout()
返回Promise
;
但我不确定这是否可靠
不是一个干净的解决方案,但是您可以尝试setTimeout来强制代码在注销进行时等待。
var timeToLogoutInMs = 500;
setTimeout(function() {
// Nothing
}, timeToLogoutInMs);
编辑:为什么你需要在beforeunload钩子上做这个?为什么不设置一个手动选项用户退出?