使用 Jquery.ajax().then() 时无法 .catch() 出错

Posted

技术标签:

【中文标题】使用 Jquery.ajax().then() 时无法 .catch() 出错【英文标题】:Cannot .catch() an error when using Jquery.ajax().then() 【发布时间】:2019-03-17 13:37:21 【问题描述】:

我正在使用 JQuery 中的许多 API,并缓存每个 API 的结果,以便可以在页面中多次重复使用数据,以呈现不同格式的一些仪表板小部件。

问题是,如果 API 返回 500 错误状态码,我不想尝试绘制小部件,而是以友好的方式捕获错误。

但是,我无法弄清楚 .catch 如何与 JQuery.ajax() 函数一起使用。在阅读了here、here、here、here 和其他十几个之后,我已经到此为止了,但总是得到相同的控制台错误:

TypeError: LoadDataFromApi(...).then(...).catch 不是函数

我已尝试对代码进行注释以解释我在每个阶段要执行的操作。请有人解释为什么整个.catch 对我不起作用。

// Cache object to save API data for re-use
var requestCache = ;

// Get API data and save to cache 
function LoadDataFromApi(apiUrl) 
    if (!requestCache[apiUrl]) 
        var result = $.ajax(
            type: 'GET',
            url: apiUrl,
            dataType: "json",
            statusCode: 
                500: function (xhr) 
                    var err = JSON.parse(xhr.responseText);
                    console.log('Message:' + err.Message);
                    // throw err.Message; // removed because this was always an "uncaught exception", even if used within try/catch
                ,
                200: function (xhr) 
                    // Do nothing here - put result into cache regardless of status code
                
            
        );
        requestCache[apiUrl] = result; // save the JSON data into cache
    
    return requestCache[apiUrl];


// Called by page on load
function LoadJsonData() 
    LoadDataFromApi('/api/GetFoo?Row=10')
        .then(function (data) 
            RenderChart(data, 'Removed for legibility');
        )
        .catch(function (error) 
            console.log('Promise catch: ' + error);
        );
    LoadDataFromApi('/api/GetFoo?Row=10') // this returns cached data because API has already been hit
        .then(function (data) 
            RenderChart(data, 'Removed for legibility');
        )
        .catch(function (error) 
            console.log('Promise catch: ' + error);
        );
    LoadDataFromApi('/api/GetBar')
        .then(function (data) 
            RenderChart(data, 'Removed for legibility');
        )
        .catch(function (error) 
            console.log('Promise catch: ' + error);
        );

【问题讨论】:

jquery 也有它自己的 Promise 实现(基本上是因为他们在 Promise 成为事物之前就这样做了)。它需要fail 而不是catch 调用。 我知道这是一个很大的问题,但从那天起我的头就晕了。您能否帮助应用该重新结构,以便我可以看到这一点?尊重缓存非常重要,因此 API 不会被不必要地调用两次,正是这种复杂性使得这变得更加难以掌握。 @Liam 我认为你错了——看看LoadDataFromApi 的实现——它显然返回jQuery.ajax() 结果,而不是缓存对象本身:) 是的,我刚刚看到@SzybkiSasza,抱歉 今天早上的咖啡显然不够。 【参考方案1】:

使用.fail(),如您的第一个链接here中所述

取决于你的 jQ 版本

"弃用通知:jqXHR.success()、jqXHR.error() 和 jqXHR.complete() 回调从 jQuery 3.0 开始被移除。您可以使用 jqXHR.done()、jqXHR.fail() 和 jqXHR.always() 代替。”

编辑: 你的错误回调应该接受 3 个参数,所以这样做

function(jqXHR,textStatus,errorThrown )

【讨论】:

根据另一个答案的评论,我已经把它换掉了,但是我该如何询问剩下的对象以获取那里的数据? 啊太棒了,这就是问题所在。我看到 JSON 数据在 jqXHR 中,这很棒。现在一切正常。谢谢。【参考方案2】:

JQuery 不返回典型的承诺,在这种情况下是$.Deferred

http://api.jquery.com/jquery.ajax/ http://api.jquery.com/category/deferred-object/

更多关于这里,答案: Deferred versus promise

【讨论】:

好的...如果我将.catch 换成.fail (function(error) ...,控制台将显示输出Promise catch: [object Object]。请问如何查询这个以获取错误详细信息或其中存在的任何内容?

以上是关于使用 Jquery.ajax().then() 时无法 .catch() 出错的主要内容,如果未能解决你的问题,请参考以下文章

jQuery AJAX 调用中是不是有任何类似于“终于”的东西?

当 jQuery Ajax 调用完成时控制请求

复选框状态更改时如何更新mysql字段?使用 jquery (ajax)、php 和 mysql

JQuery Ajax - 如何在进行 Ajax 调用时检测网络连接错误

使用 jQuery.ajax 发送 multipart/formdata

使用 jQuery.ajax 发送 multipart/formdata