【问题标题】:Can I manually resolve a deferred object if a callback might need to reject it?如果回调可能需要拒绝它,我可以手动解析延迟对象吗?
【发布时间】:2013-02-26 18:17:58
【问题描述】:

我正在尝试使用自定义延迟对象来管理一些回调。我想出了一个简单的案例:

var deferred = $.Deferred();

deferred.done(function() {
    console.log( 'done' );
});

var json = $.getJSON('/foo');

json.then(
    function() {
        deferred.resolveWith(this, arguments);
    }  
);

但我需要在解决/拒绝之前检查响应。我想添加如下内容:

deferred.pipe(
    function(response) {
        if (response.message === 'error') {
            return $.Deferred.reject(response);
        }
        return response;
    }
);

但是当我这样做时,我原来的done() 回调总是会被调用。我很确定这是因为一旦我打电话给deferred.resolveWith(),“回滚”并将其标记为稍后被拒绝就太晚了。我知道我可以将条件移到json.then() 的第一个参数中,但这似乎忽略了延迟对象的意义——我认为它们是为了将所有这些行为封装到一个地方。

是否可以将条件和回调都放入deferred,同时仍然在其他地方解决它?

【问题讨论】:

  • 请注意,.pipe 在最近的版本中已被贬低,请使用.then 代替它。
  • deferred.pipe 在哪里适合您的原始代码?我不太明白为什么要将请求的参数测试与请求的完成回调分开。正如你所说,既然已经在 done 回调中解决了,你不能回去拒绝它。
  • @KevinB deferred.pipe (或 deferred.then)可以去定义 deferred 的其余部分,而不是在 ajax 调用之后。我的问题可能是一个概念性的问题——也许将响应测试和回调封装在一个对象中合适?但在这种情况下,ajax 调用本身嵌套在一堆条件和回调中。将工作流定义为单个对象并稍后引用它似乎是模块化它的最佳方式。
  • 这是否更接近您想要做的事情? pastebin.com/v9XHmiGQ 在发送 ajax 请求之前完全设置延迟?
  • 为什么不在原始成功处理程序中检查 response.message 并酌情调用 resolveWith/rejectWith?

标签: jquery jquery-deferred


【解决方案1】:

您的目标似乎只是将功能分为两个步骤:验证 ajax 请求的结果,然后处理结果。为此,请使用一个内部 deferred 替换外部 deferred,该内部 deferred 根据 ajax 请求返回的参数解析或拒绝。

var deferred = $.Deferred();

deferred.then(function(data){
    // new deferred that we will be returning
    var deferred = $.Deferred();
    if (data.success == true) {
        deferred.resolveWith(data.result);
    }
    else {
        deferred.rejectWith(data.error);
    }
    // any following chained methods will affect this returned deferred object
    return deferred;
}).then(
    // done callback
    function(result){
        console.log("Resolved!");
        console.dir(result);
    },
    // fail callback
    function(error){
        console.log("Rejected!");
        console.dir(error)
    }
);

var json = $.getJSON("/foo");
json.done(deferred.resolveWith);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 2010-12-07
    • 2012-01-15
    相关资源
    最近更新 更多