2

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

foo = $.Deferred();

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

return foo.promise();

上面的代码不起作用,返回的承诺没有a_method,而只有 jQuery 的默认承诺方法。我现在的想法是:

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

return $.extend(foo.promise(), myMixin);

该代码按预期工作,但并不是每个人都通用(至少,我认为),而且理解起来也不是很简单。

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

有更好的方法吗?

4

2 回答 2

4

Promise对象与对象不同Deferred。调用promise()一个Deferred对象会创建一个新Promise对象。由于您将函数添加到Deferred对象中,因此它们不存在于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
于 2013-06-26T15:27:46.930 回答
2

有更好的方法。

Deferred.promise([target])的 jQuery 文档说:

如果提供了目标,deferred.promise()则将方法附加到它上面,然后返回这个对象而不是创建一个新对象。这对于将 Promise 行为附加到已经存在的对象很有用。

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

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;
}

通过返回thisor 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('*');

如您所见, 中定义的方法é可用于任何使用dfrd.promise(é).

演示

于 2014-04-18T21:39:36.193 回答