1

我们正在组合一个 FSSO API,它需要一个弹出窗口供用户登录。在弹出窗口中,我们执行两个任务:

  1. 调用服务以填充配置文件值,然后设置页面以根据事件类型(登录或注册)将用户重定向到。

  2. 将用户重定向到父窗口中的重定向页面并关闭 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 但没有运气的技巧,我只尝试了没有超时的回调。

在这里寻找处理此类时间问题的最佳实践,我现在感觉很糟糕。:)

4

2 回答 2

1

您应该将回调称为成功函数的最后一个操作:

.
.
.
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
                }
      });
      }
于 2013-08-21T23:12:54.483 回答
1

调用$.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. 请注意,完成将在成功和错误条件下执行,因此您可能只想在成功处理程序中调用回调,并对任何错误执行其他操作。

于 2013-08-21T23:19:56.267 回答