这是一个“延迟反模式”?

我发现很难理解“延迟反模式”。 我认为我理解它的原则,但我还没有看到一个超级简单的例子是什么服务,有不同的承诺,有一个反模式,所以我想我会尽我所能,但看到我不怎么样超级在知道它我会得到一些澄清第一。

我在下面的工厂(SomeFactory):

//url = 'data.json'; return { getData: function(){ var deferred = $q.defer(); $http.get(destinationFactory.url) .then(function (response) { if (typeof response.data === 'object') { deferred.resolve(response.data); } else { return deferred.reject(response.data); } }) .catch(function (error) { deferred.reject(error); }); return deferred.promise; } 

我检查它的一个对象的原因只是添加一个简单的validation层到$http.get()

在下面,在我的指示:

 this.var = SomeFactory.getData() .then(function(response) { //some variable = response; }) .catch(function(response) { //Do error handling here }); 

现在据我的理解,这是一个反模式。 因为最初的延期承诺会捕获错误,并简单地吞下它。 它不返回错误,所以当这个“getData”方法被调用时,我已经做了另一个抓住错误。

如果这不是一个反模式,那么有人可以解释为什么都需要“callback”的种类? 当我第一次开始编写这个工厂/指令时,我预期在某个地方需要做出承诺的承诺,但是我并没有预料到在双方都需要.catch().catch()我可以让工厂返回响应或错误,如果我做了一个SomeFactory.getData()

这是一个“延迟反模式”?

是的。 当从冗余链中创build新的冗余延迟对象时,会发生“延迟反模式” 。 在你的情况下,你正在使用$ q返回一个承诺,隐式返回一个承诺。 你已经有一个Promise对象( $http service本身返回一个promise ),所以你只需要返回它!

这里是一个非常简单的例子,一个服务,一个不同的承诺和一个反模式的样子,

这是反模式

 app.factory("SomeFactory",['$http','$q']){ return { getData: function(){ var deferred = $q.defer(); $http.get(destinationFactory.url) .then(function (response) { deferred.resolve(response.data); }) .catch(function (error) { deferred.reject(error); }); return deferred.promise; } } }]) 

这是你应该做的

 app.factory("SomeFactory",['$http']){ return { getData: function(){ //$http itself returns a promise return $http.get(destinationFactory.url); } } 

而他们两个都以同样的方式消耗。

 this.var = SomeFactory.getData() .then(function(response) { //some variable = response; },function(response) { //Do error handling here }); 

这两个例子都没有错(至less在语法上),但是第一个是多余的,不需要!

希望它有助于:)

我会说这是经典的延迟反模式,因为你正在创build不必要的延迟对象。 但是,您正在为链条添加一些价值(通过您的validation)。 通常,国际海事组织(IMO)的反模式在延迟对象创build时很less或没有任何好处时尤其糟糕。

所以,代码可以简单得多。

$q承诺有一个自动包装在承诺的承诺(使用$q.when )内返回的一些loggingfunction。 在大多数情况下,这意味着你不应该手动创build一个延期:

 var deferred = $q.defer(); 

但是,这就是文档如何演示如何使用$q来承诺。

所以,你可以改变你的代码:

 return { getData: function(){ return $http.get(destinationFactory.url) .then(function (response) { if (typeof response.data === 'object') { return response.data; } else { throw new Error('Error message here'); } }); // no need to catch and just re-throw }); }