在promise对象返回完成后调用$ .ajax statusCode处理程序

时间:2013-03-09 23:07:21

标签: ajax error-handling http-status-code-404

我正在尝试为我的淘汰视图模型编写一些qunit单元测试,我遇到了一个有趣的问题。

在我的视图模型中,我有以下功能:

    Get = function (id) {
        return $.ajax({
            url: API + "/" + id,
            type: 'GET',
            dataType: 'json',
            timeout: Timeout,
            statusCode: {
                200: GetOneSuccess,
                404: ItemNotFound
            },
            error: function () {
                //Item(null);
            }
        });
    },

然后在我的单元测试中我有这个:

vm.Get(vm.Item().Id()).then(function () {                    
   ok(false, "Failure!");
},function () {
   equal(vm.Item(), null, "Item was removed");
   start();
});

ItemNotFound如下:

    ItemNotFound = function () {
        Item(null);
    }

这非常简单,如果API控制器返回“NotFound(错误404)”,则将Item设置为null。我发现我的测试失败了,因为当“then”被称为ItemNotFound函数时还没有完成。

如果我在单元测试中添加超时,则可以:

            vm.Get(vm.Item().Id()).then(function () {                    
                    ok(false, "Failure!");
            },function () {
                    setTimeout(function () {
                        equal(vm.Item(), null, "Item was removed");
                        start();
                    }, 2000);
            });

有人有什么想法吗?我应该不打扰statusCodes并只处理错误处理程序中的所有错误类型?看起来不那么优雅。

1 个答案:

答案 0 :(得分:0)

在触发状态代码函数之前,首先触发错误处理程序。 “then”函数采用“成功回调”和“错误回调”。所以从本质上讲,你的错误(失败)是在状态代码“notfound”触发之前触发的。

当您设置超时时,该函数会立即返回,触发您的状态代码,然后根据您设置的超时,触发该特定代码。

如果您仍然需要代码结构,那么我就是这样做的。您的GET函数应该返回一个Deffered promise对象,该对象封装了实际的ajax调用,并且没有指定成功或错误处理程序,并首先从statusCode调用您的成功或错误函数。

我为同一个

创造了一个小提琴

http://jsfiddle.net/sujesharukil/BWA9D/15/

var data = {
    json: $.toJSON({
        text: 'some text',
        array: [1, 2, 'three'],
        object: {
            par1: 'another text',
            par2: [3, 2, 'one'],
            par3: {}
        }
    })
}


var callEcho = function(url) {
    return $.Deferred(function(def){
        $.ajax({
        url: url,
        type: "POST",
        data: data,
        statusCode: {
            200: function(data,xhr){
                GetOneSuccess();
                def.resolve(data);
            },
            404: function(xhr){
                ItemNotFound();
                def.reject();
            }
        }
    });    
}).promise();

};

function GetOneSuccess(){
    alert('Get One success Called');
}

function ItemNotFound(){
    alert('Item Not Found Called');
}

var testFunc = function(url){
    var js = callEcho(url);
    js.done(function(data){
        alert(JSON.stringify(data) + ' done function called');
    });

    js.fail(function(){
        alert('fail function called.');
    });
}

//fire the success
testFunc("/echo/json/" );

//fire the fail
testFunc("/echo/jso/");