Javascript 在成功的AJAX调用后修改传递给jQuery done()回调的参数

Javascript 在成功的AJAX调用后修改传递给jQuery done()回调的参数,javascript,jquery,ajax,promise,Javascript,Jquery,Ajax,Promise,以下是场景: 我需要通过AJAX从服务器获取一些JSON数据(ASP.NET MVC应用程序+ServiceStack服务)。如果用户的会话过期,那么我不会返回JSON,而是重定向到登录页面,该页面由jQuery自动执行,因此AJAX调用的结果最终是登录表单的原始HTML。我需要以不同的方式处理这两种情况: 如果结果是JSON,则使用.done()promise来更新UI 如果结果是HTML,则弹出一个登录对话框 因此,我必须修改传递给done()回调函数的参数。以下是我迄今为止所尝试的:

以下是场景:

我需要通过AJAX从服务器获取一些JSON数据(ASP.NET MVC应用程序+ServiceStack服务)。如果用户的会话过期,那么我不会返回JSON,而是重定向到登录页面,该页面由jQuery自动执行,因此AJAX调用的结果最终是登录表单的原始HTML。我需要以不同的方式处理这两种情况:

  • 如果结果是JSON,则使用
    .done()
    promise来更新UI
  • 如果结果是HTML,则弹出一个登录对话框
因此,我必须修改传递给
done()
回调函数的参数。以下是我迄今为止所尝试的:

function getSomeData() 
{
    return $.ajax(
    {
        /* 
            ...set my AJAX config options... 
        */,
        error: function(xhr, status, errorText)
        {
            // handle the error
        },
        success: function(data) 
        {
            // if the AJAX call returned a login form instead of expected JSON 
            // result (because the user's session has expired) then show a 
            // login dialog and resolve the jQuery promise with 'null' instead 
            // of original 'data'

            if (isLoginFormHTML(data)) 
            {
                showModalLoginDialog(data);
                data = null;    // neither this...
                return null;    // ... nor this seem to work!
            }
        }
    });
}

function updateUI()
{
    getSomeData().done(function(jsonData)
    {
        if (jsonData)
        {
            // do something 
        }
    });
}
不幸的是,无论我在
success
函数中执行
data=null
还是
return null
,传递给
done()
回调函数的参数都包含从服务器返回的原始
数据,如果会话已过期,这些数据可能是登录表单的HTML

所以问题是,我如何告诉jQuery将其他内容传递给
done()


p.S.当然,我可以在
updateUI
方法中执行
isLoginFormHTML()
检查,但为了保持数据检索和UI更新逻辑分离,我试图避免这种情况。

您应该使用
返回所需值的承诺。然后,
,承诺有一个很酷的地方,那就是它们是连锁的

function getSomeData() 
{
    return $.ajax({
        /* 
            ...set my AJAX config options... 
        */,
        error: function(xhr, status, errorText)
        {
            // handle the error
        }).then(function(data){

            if (isLoginFormHTML(data)) {
                showModalLoginDialog(data);
                throw new Error("Unauthorized");..
            }
            return data;
        }
    });
}
这将允许您执行以下操作:

    getSomeData().done(function(jsonData){
        //yay data   
    }).fail(function(){
       //no data
    });

这并不能回答您的问题,但我的第一个冲动是在会话过期时返回错误,而不是返回HTML。然后,您可以通过拉取和显示登录表单来处理该特定错误。此外,即使出现错误,也会调用done(),因此您可能希望使用getSomeData().success()无论您如何处理登录HTML。请使用
。然后使用
而不是
成功:
Dave:我无法控制服务器的响应,因为重定向到登录页面是由我的ASP.NET MVC应用程序使用的FormsAuthentication自动完成的。Benjamin Grunbaum:感谢您的建议,它看起来很有希望。一旦找到解决方案,我会更新我的帖子。@caspinanuck这就是解决方案,
success:
不是承诺的延续。返回
$.ajax(..).then(function(){…
),如果您想发出错误信号,我建议您改为抛出,以导致承诺被拒绝(如同步抛出)。