[英]JavaScript timing issue - window closing before sessionStorage values are set
我们正在组合一个FSSO API,该API需要一个弹出窗口供用户登录。在弹出窗口中,我们执行两项任务:
调用服务以填充配置文件值,然后设置页面以根据事件类型(登录或注册)将用户重定向到。
将用户重定向到父窗口中的重定向页面,然后关闭FSSO弹出窗口。
码:
$(document).ready(function() {
var nextPage = "index.html",
storage = window.opener.sessionStorage;
function setStorage(callback){
$.ajax({
type: "GET",
cache: false,
dataType: "json",
url: "https://someserviceURL/service/profile",
success: function(objJSON){
//storage.op is set on the parent page when login or reg link is clicked
if (storage.op == "login") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true)); //Some browsers don't support booleans in sessionStorage
nextPage = "dashboard.html";
}
else if (storage.op == "register") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true));
nextPage = "options.html";
}
},
error: function( jqXHR, textStatus, errorThrown){
//display error message
}
});
callback();
}
setStorage(function(){
if (typeof window.opener != "undefined" && window.opener != null){
setTimeout(function(){
window.opener.location.href = nextPage;
window.close();
},3000);
}
});
});
问题:如果我将超时设置为小于3000的任何东西,那么在我可以设置sessionStorage值之前,该窗口似乎正在关闭。我只是想关闭窗口以响应那些设置的值,而不是任意的时间量通过。 我尝试了将超时设置为0但没有运气的技巧,并且尝试了没有超时的回调。
在这里寻找处理此类时序问题的最佳做法,我现在觉得很棘手。 :)
您应该将回调作为成功函数的最后一个动作:
.
.
.
else if (storage.op == "register") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true));
nextPage = "options.html";
}
callback(); // execute your callback to the window closer here.
},
error: function( jqXHR, textStatus, errorThrown){
//display error message
}
});
}
$.ajax()
的调用是异步的,这意味着脚本的其余部分将在调用后立即继续执行,而无需等待调用完成并触发成功或错误处理程序。
这意味着在成功处理程序之前,将执行称为callback
函数。 它通常可以按预期的方式工作,超时时间为3000毫秒,因为您的Web服务所需的时间通常少于此时间,因此在这种情况下,请先执行回调。 如您所述,这不是控制事件顺序的可靠方法。
一种解决方案是将回调作为完整处理程序的一部分执行,如下所示:
$(document).ready(function() {
var nextPage = "index.html",
storage = window.opener.sessionStorage;
function setStorage(callback){
$.ajax({
type: "GET",
cache: false,
dataType: "json",
url: "https://someserviceURL/service/profile",
success: function(objJSON){
//storage.op is set on the parent page when login or reg link is clicked
if (storage.op == "login") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true)); //Some browsers don't support booleans in sessionStorage
nextPage = "dashboard.html";
}
else if (storage.op == "register") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true));
nextPage = "options.html";
}
},
error: function( jqXHR, textStatus, errorThrown){
//display error message
},
complete: function( jqXHR, textStatus){
callback();
}
});
}
setStorage(function(){
if (typeof window.opener != "undefined" && window.opener != null){
window.opener.location.href = nextPage;
window.close();
}
});
});
或者,如果您不关心返回的参数,则可以直接传递callback
来complete
。 请注意,complete将在成功和错误条件下执行,因此您可能只想在成功处理程序中调用callback并执行其他任何错误处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.