2016-02-26 3 views
6

Я видел ответы на StackOverflow, где люди предлагают предоставить функцию обратного вызова службе AngularJS.Почему обратные вызовы от Promise `.then` Методы Анти-Pattern

app.controller('tokenCtrl', function($scope, tokenService) { 
    tokenService.getTokens(function callbackFn(tokens) { 
     $scope.tokens = tokens; 
    }); 
}); 

app.factory('tokenService', function($http) { 
    var getTokens = function(callbackFn) { 
     $http.get('/api/tokens').then (function onFulfilled(response) { 
      callbackFn(response.data); 
     }); 
    }; 

    return { 
     getTokens: getTokens 
    }; 
}); 

Мне кажется, что это Anti-Pattern. Служба $http возвращает обещания, а методы .then выполняют функции обратного вызова, похоже на нездоровое обращение к управлению.

Как один рефакторинг код как этот и как объяснить, почему исходным способом был Неплохая идея?

+2

Просто скажите людям, что они фактически используют обещания вместо того, чтобы игнорировать их. – SLaks

+0

Я нашел использование 'обещания', это здорово, так как он обладает способностью связывать его и контролировать асинхронный вызов. –

+4

Основная проблема заключается в том, что ничего не возвращается в 'then()' негде ловить ошибки в обратном вызове. Это ломает цепочку обещаний – charlietfl

ответ

0

Этот код может быть повторно факторизованные следующим образом:

app.controller('tokenCtrl', function($scope, tokenService) { 
    tokenService.getTokens.then (callbackFn(tokens) { 
     $scope.tokens = tokens; 
    }); 
}); 

app.factory('tokenService', function($http) { 
    var getTokens = function() { 
     //return promise 
     return $http.get('/api/tokens').then (function onFulfilled(response) { 
       //return tokens 
       return response.data; 
      } 
     ); 
    }; 

    return { 
     getTokens: getTokens 
    }; 
}); 

При наличии службы возвращают обещание, и используя .then метод обещание, та же функциональность достигается со следующими преимуществами:

  • Обещание может быть сохранено и использовано для chaining.

  • Обещание можно сохранить и использовать, чтобы избежать повторения того же звонка $http.

  • Информация об ошибках сохраняется и может быть получена методом .catch.

  • Обещание может быть отправлено другим клиентам.

7

Вы должны изменить его

var getTokens = function() { 
     return $http.get('/api/tokens'); 
    }; 

А, то в другом использовании модуля

yourModule.getTokens() 
    .then(function(response) { 
    // handle it 
    }); 

Относительно того, почему это анти-паттерн, я бы сказал, что, во-первых, это Безразлично 't позволяет вам далее объединять методы успеха/неудачи. Во-вторых, он обрабатывает управление обработкой ответа от вызывающего модуля на вызываемый модуль (что здесь может быть не очень важно, но оно все еще накладывает такую ​​же инверсию управления). И, наконец, вы добавляете концепцию обещаний в свою кодовую базу, что может быть не так просто понять для некоторых из товарищей по команде, но затем использовать обещания как обратные вызовы, так что это действительно бессмысленно.

+0

Отредактировано с объяснениями, спасибо) –

Смежные вопросы