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

问题描述:

我想为我的挖空视图模型编写一些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(Error 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,只处理错误处理程序中的所有错误类型?看起来不那么优雅。

错误处理程序在状态代码函数被触发之前被触发。 “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/");