$ .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/");