使用jQuery中的自定义方法返回承诺

使用jQuery中的自定义方法返回承诺,jquery,jquery-deferred,Jquery,Jquery Deferred,我需要返回一个作为承诺的自定义js对象,也就是说,当延迟被解析或拒绝时,我可以附加回调或错误回调。我需要在这个对象中使用一些自定义方法,只有当它本身不是“挂起”时才能运行这些方法。有点像: foo = $.Deferred(); foo.a_method = function() { // do something only if "this" is resolved or rejected // throw an exception instead }; return fo

我需要返回一个作为承诺的自定义js对象,也就是说,当延迟被解析或拒绝时,我可以附加回调或错误回调。我需要在这个对象中使用一些自定义方法,只有当它本身不是“挂起”时才能运行这些方法。有点像:

foo = $.Deferred();

foo.a_method = function() {
    // do something only if "this" is resolved or rejected
    // throw an exception instead
};

return foo.promise();
上面的代码不起作用,返回的承诺没有
a_方法
,只有jQuery的默认承诺方法。我现在的想法是:

var myMixin = {
    a_method: function() {
        // ...
    }
};

return $.extend(foo.promise(), myMixin);
该代码按预期工作,但它不是每个人都通用的(至少,我认为),而且理解起来也不是很简单

我想要它的原因是,我有一个lib,它依赖于一些加入的ajax请求(
$。when($.ajax('foo'),$.ajax('bar'))
),以便更好地执行。所以我做了 请求,附加一些其他回调,并使用“特定于域”的方法返回此链的承诺


有更好的方法吗?

Promise对象与
Deferred
对象不同。对
延迟的
对象调用
promise()
,将创建一个新的
promise
对象。由于您已将函数添加到
延迟的
对象中,因此它们在
承诺
中不存在。因此,您需要将它们添加到
Promise
对象本身

$.extend
调用中,您正是这样做的。正如你所说,语法有点难。因此,您可以使用上面的简单语法:

foo = $.Deferred().promise(); // store the promise object

foo.a_method = function() { // add the property to the Promise object
    // do something only if "this" is resolved or rejected
    // throw an exception instead
};

return foo; // return the Promise object
有更好的办法

jQuery文档说明:

如果提供了目标,
deferred.promise()
会将方法附加到目标上,然后返回此对象,而不是创建新对象。这对于将承诺行为附加到已经存在的对象非常有用

因此,您可以如下定义自己的promise方法:

var myPromiseMethods = {
    myMethod1: function() {
        ...
    },
    myMethod2: function() {
        ...
    },
    myMethod3: function() {
        ...
    }
};
var dfrd = $.Deferred();
...
return dfrd.promise(myPromiseMethods).myMethod();
然后,您可以按如下方式使用您的方法:

var myPromiseMethods = {
    myMethod1: function() {
        ...
    },
    myMethod2: function() {
        ...
    },
    myMethod3: function() {
        ...
    }
};
var dfrd = $.Deferred();
...
return dfrd.promise(myPromiseMethods).myMethod();
通常,您会希望编写类似以下内容的方法:

myMethod1: function() {
    var promise = this;
    //do something awesome here 
    return promise;
}
通过返回
this
promise
,该方法与内置的promise方法类似,可以链接,例如:

var dfrd = $.Deferred();
...
return dfrd.promise(myPromiseMethods).myMethod().then(...);
例子 您可以在任何方便的范围内定义包含自定义方法的对象。在本例中,我只将对象命名为
é
(Windows下的altGreen-E),它紧凑、独特,不太可能用于其他目的

因此,让我们定义一个
invert()
方法,该方法将承诺的意义颠倒过来-resolve变为reject,reject变为resolve

var é = {
    invert: function() {
        var promise = this;
        return $.Deferred(function(dfrd) {
            promise.then(dfrd.reject, dfrd.resolve);
        }).promise();
    }
};

var dfrd = $.Deferred();
dfrd.promise(é).invert().done(function(str) {
    alert('done: ' + str);
}).fail(function(str) {
    alert('fail: ' + str);
});
dfrd.reject('*');
如您所见,
ee
中定义的方法可用于使用
dfrd.promise(ee)
创建的任何promise


似乎对我有效->(不必担心全球人)请解释你为什么要尝试实现这一目标-可能有更好的整体方法。@adeneo,我认为这只是因为你误解了这个问题。你能以任何方式工作的唯一原因是因为globals。@lonesomeday-我明白为什么它能工作,因为foo是全局的,但它仍然可以在没有globals的情况下工作->但是在同一范围内有一个promise对象和一个deferred对象肯定会使promise对象冗余。OP希望向特定的promise对象添加一个方法。他的误解是,他被添加到延迟对象中。