我可以从AJAX延迟回调中访问Deferred对象吗?

时间:2012-08-27 19:42:53

标签: jquery

有没有办法可以从ajax的成功回调中访问内部Deferred对象?我希望能够将一个ajax调用的抽象传递给一个函数,但是能够将该函数调用包装在$ .when()中并使用reject()和resolve()将参数传递回我的done()和fail()回调如此:

 $.when(makeCall())
 .done(function(data){
     //do something with data
  })
 .fail(function(message){
     //show error
  });

 function makeCall(){
     return $.ajax({
         url : //some url,
         success : function(data){
              if(!data.someCondition){
                 //i'd like to reject the internal deferred here
                 //and send it back an error message to my
                 //the callers fail method like reject('message')
              }
              else{
                 //i'd like to resolve the deferred here and 
                 //pass back the data to the callers done
                 //method like resolve(data)
              }
         }
     });
 }

现在我将makeCall()包装在另一个Deferred对象中,并在ajax回调中解析或拒绝那个,但感觉我应该能够在没有额外的Deffered包装器的情况下执行此操作。

2 个答案:

答案 0 :(得分:1)

不,此时已经解决或拒绝了。您必须创建自己的延迟才能获得此功能。

$.when(makeCall())
 .done(function(data){
     //do something with data
  })
 .fail(function(message){
     //show error
  });

 function makeCall(){
     var def = $.Deferred();
     $.ajax({
         url : //some url,
         success : function(data){
              if(!data.someCondition){
                 // reject it
                 def.rejectWith(data.someCondition);
              }
              else{
                 // resolve it
                 def.resolveWith(data);
              }
         }
     });
     return def.promise();
 }

编辑:抱歉,我没有意识到这已经是您尝试过的并且正在努力避免。问题是在成功回调中,延迟对象已经解决。在那一点上它无法撤消。

修改
Woudln让您的服务器在发生错误时返回错误状态代码而不是200会更有意义吗?此时,您可以将响应文本解析为json并适当地处理错误,而不会更加干扰延迟对象。

答案 1 :(得分:0)

我需要这样做以防止竞争条件 - 我想完全忽略一些回应

一旦我发现我无法拒绝原来的延期,我最终做了这样的事情。不理想,但为我需要的东西工作。当然,即使我能够拒绝延迟(或创建我自己的),这可能不是我想要的,因为它也不是真正的失败条件。

function makeCall()
{
     return $.ajax({
         url : //some url,
         success : function(data)
         {
              if (!data.someCondition)
              {
                 data.ignore = true;
              }
         }
     });
 }


 makeCall().done(function(data) 
 {
      if (data.ignore) 
      {
          return;
      }
 });