[英]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.