【问题标题】:Modifying the argument passed to jQuery done() callback following a successful AJAX call在成功的 AJAX 调用之后修改传递给 jQuery done() 回调的参数
【发布时间】:2014-06-07 02:34:51
【问题描述】:

场景如下:

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

  • 如果结果是 JSON,则使用它使用 .done() 承诺更新 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()回调的参数都包含从服务器返回的原始data,可能是HTML会话过期时的登录表单。

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

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

【问题讨论】:

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

标签: javascript jquery ajax promise


【解决方案1】:

你应该使用.then返回一个你需要的值的promise,promise的一个很酷的地方是它们可以链接。

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
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2010-11-14
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多