Coffeescript和AngularJS中的隐含回报

时间:2013-09-18 14:16:48

标签: angularjs coffeescript

Coffeescript中的以下虚拟控制器:

GlobalTimelineController = ($scope, $http) ->
  $http.get('/api/globalTimeline').success (posts) ->
    $scope.posts = posts

按如下方式编译为Javascript:

(function() {
  var GlobalTimelineController;

  GlobalTimelineController = function($scope, $http) {
    return $http.get('/api/globalTimeline').success(function(posts) {
      return $scope.posts = posts;
    });
  };

}).call(this);

我想知道Coffee编译器添加的这些 return 语句的副作用是什么?正确性和性能都明智吗?

我应该关心这个并且在我的方法和回调结束时返回空白吗?

2 个答案:

答案 0 :(得分:1)

$ http.get调用返回一个所谓的“promise”,其工作方式如下:

promise.success = function(fn) {
  promise.then(function(response) {
    fn(response.data, response.status, response.headers, config);
  });
  return promise;
};

取自AngularJS源代码(/src/ng/http.js:700)

这意味着无论你的函数返回什么都被忽略,所以如果它是object,那么在你的函数完成后它的引用就会丢失。 因此,从正确的角度来看,它并不重要。

现在,如果我们看一下表现,在这种情况下,差异(如果有的话)可以忽略不计。 但是,您始终需要牢记这一行为。如果您在函数中执行的最后一件事是执行一些具有多次迭代的循环,则coffeescript将返回一个由每个数组迭代的结果组成的大数组(数组理解)。它不仅会影响性能,而且在极端情况下可能会导致JS内存不足!

您还可以在末尾附加一个return语句,以防止coffeescript生成此类数组。

答案 1 :(得分:1)

TLDR;如果不认为你应该担心这一点。

前一段时间处理的唯一问题与单元测试控制器方法有关。

比方说,在你的单元测试中,你有类似的东西:

  beforeEach inject ($injector)->
    $controller       = $injector.get '$controller'
    injectables   = { ... }
    ctrl = $controller 'app.controllers.FooBarCtrl', injectables


  describe 'Controller ...', ->
    it 'should have foo property', ->
      expect(ctrl.foo).toBeDefined()

你的控制器看起来像这样:

name = 'app.controllers.FooBarCtrl'
angular.module(name, []).controller(name, [

  '$scope'
  '$http'

  ($scope)->
    scope.foo = 'bar'
    $http.get '/foo/bar', (res)-> console.log 'response: ', res

])

在这种情况下,您将无法测试任何控制器方法,因为返回的内容实际上是一个承诺。为了获得对实际控制器方法的访问,您需要返回它,如下所示:

name = 'app.controllers.FooBarCtrl'
angular.module(name, []).controller(name, [

  '$scope'
  '$http'

  ($scope)->
    scope.foo = 'bar'
    $http.get '/foo/bar', (res)-> console.log 'response: ', res

    @ # <--- look ma, I'm here!
])

但是,从实际的角度来看,我认为这些示例并不是非常相关,因为在单元测试角度控制器时,您应该实际处理带有$ scope的API,并将控制器方法视为私有(实现细节)。