这是一个“延迟反模式”?
我发现很难理解“延迟反模式”。 我认为我理解它的原则,但我还没有看到一个超级简单的例子是什么服务,有不同的承诺,有一个反模式,所以我想我会尽我所能,但看到我不怎么样超级在知道它我会得到一些澄清第一。
我在下面的工厂(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 }); }