0

I'm writing an AngularJS service for a SignalR hub. Here's my factory for the service:

.factory('gameManager', [function () { 
        $.connection.hub.start();
        var manager = $.connection.gameManager;
        return manager;
    }])

That code would be perfect, except that that .start() call is asynchronous, and the hub has not completed starting by the time the manager is returned. Basically, I want to block until the start is complete before returning the manager. The .start() method returns a Jquery deferred object, which I'm guessing is part of the answer, but I don't know how to use it without a callback function?

4

2 回答 2

3

像下面这样的东西应该可以解决问题。

app.factory('gameManager', [function () { 
    return $.connection.hub.start().then(function() {
      return $.connection.gameManager;
    });
}])

现在你的回调函数也将返回一个延迟/承诺,所以服务消费者需要期待这一点。您的消费代码可能如下所示:

gameManager.then(function(gameManager) {

  // do whatever with game manager
  gameManager.doSomething();
});

jquery Deferred的文档在这里。特别是,检查Deferred.then()

注意:

deferred.then() 方法返回一个新的promise,它可以通过函数过滤deferred 的状态和值……这些过滤器函数可以返回一个新值,传递给promise 的.done() 或.fail( ) 回调,或者它们可以返回另一个可观察对象(Deferred、Promise 等),它将其已解决/拒绝状态和值传递给 promise 的回调...


更新

另一种方法(可能是更好的方法 - 因为它不需要您的消费者处理承诺)是让集线器在设置您的工厂之前完全初始化,并启动您的应用程序控制器。像这样的东西...

$.connection.hub.start().then(function() {
  app.factory('gameManager', function() {
    return $.connection.gameManager;
  });

  // ...
  // kick off the rest of the app..

});
于 2013-02-09T22:42:32.853 回答
0

你不会找到你要找的东西,你将不得不接受李的回答。Javascript 大多是单线程的,不允许阻塞(有特定的例外,例如警报窗口或同步 ajax 调用)。

于 2013-02-09T23:27:13.500 回答