这是"延期反模式"吗?

Ale*_*ski 17 angularjs angularjs-directive angularjs-service angular-promise

我发现很难理解"延迟反模式".我认为我原则上理解它,但我没有看到一个超级简单的例子,一个服务,一个不同的承诺和一个反模式,所以我想我会尝试自己做但看到我不是超级了解它我先得到一些澄清.

我在工厂(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;
    }
Run Code Online (Sandbox Code Playgroud)

我检查它的对象的原因只是在上面添加一个简单的验证层 $http.get()

以下,在我的指令中:

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

现在我的理解是,这是一个反模式.因为原始的延期承诺会捕获错误并简单地吞下它.它不会返回错误,因此当调用此"getData"方法时,我已经执行了另一个捕获错误的捕获.

如果这不是反模式,那么有人可以解释为什么两者都要求各种"回调"吗?当我第一次开始写这个工厂/指令时,我预计不得不在某个地方做一个默认的承诺,但我没有预料到必须.catch()在两边(也就是我有点想我可以让工厂返回响应或错误,如果我做了一个SomeFactory.getData()

nal*_*inc 22

这是"延期反模式"吗?

是的.当创建新的冗余延迟对象以从promise链中解析时,会发生"延迟反模式".在您的情况下,您使用$ 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;
        }
     }
}])
Run Code Online (Sandbox Code Playgroud)

这是你应该做的

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

而两者都以同样的方式消费.

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

两个例子(至少语法上)没有任何问题..但第一个是多余的...而且不需要!

希望能帮助到你 :)

  • 我没有登录就进行了编辑,现在它被锁定了.基本上,.success和.error已被弃用.你现在可以使用.then. (2认同)

Dav*_*yon 8

我会说这是经典的延迟反模式,因为你正在创建不必要的延迟对象.但是,您正在为链添加一些值(通过验证).通常,IMO,反模式在创建延迟对象时很少或没有任何好处.

因此,代码可以更简单.

$qpromises有一个记录的功能,可以自动包装promise(promise)中promise中返回的任何内容$q.when.在大多数情况下,这意味着您不必手动创建延迟:

var deferred = $q.defer();
Run Code Online (Sandbox Code Playgroud)

但是,这就是文档演示如何使用promises的方式$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
        });
    }
Run Code Online (Sandbox Code Playgroud)