【问题标题】:AngularJs return async factory?AngularJs 返回异步工厂?
【发布时间】:2017-09-17 23:48:21
【问题描述】:

我已经阅读了很多关于这个问题的答案,但我就是不明白。承诺去哪儿了?我通过对云数据库的异步调用创建了一个简单的工厂:

app.factory('asyncFactory', function() {

  let toController = function() {

    firebase.database().ref('en').once('value') // get the array from the cloud database
    .then(function(snapshot) { // take a snapshot
      console.log(snapshot.val()); // read the values from the snapshot
      return snapshot.val(); // this returns later
    });

    return 47 // this returns immeadiately
  };

  return {
    toController: toController // why is this necessary?
  }

});

我从我的控制器调用它:

$scope.words = asyncFactory.toController();
console.log($scope.words);

回复如下:

如您所见,47 立即返回控制器。如果我注释掉return 47,那么工厂返回undefined。稍后异步数据记录但不返回到控制器。我每天都在使用 Promise,但我无法弄清楚 Promise 的去向。

第二个问题:我需要toController: toController这行吗?我可以摆脱它吗?

谢谢!

【问题讨论】:

  • 承诺不会去任何地方,因为不是返回它,而是返回 47。阅读blog.ninja-squad.com/2015/05/28/angularjs-promises。关于“我是否需要 toController: toController 这一行”,嗯,不,但是你的服务根本没有方法,而且真的没用。

标签: angularjs firebase asynchronous angular-promise


【解决方案1】:

要在控制器中使用 firebase 调用的结果,工厂方法需要返回一个 promise:

app.factory('asyncFactory', function($q) {    
  return {
    toController: toController
  };

  function toController() {

    var es6promise = firebase.database().ref('en').once('value');

    var qPromise = $q.when(es6promise)
      .then(function(snapshot) { // take a snapshot
        console.log(snapshot.val()); // read the values from the snapshot
        return snapshot.val(); // this returns later
    });

    return qPromise;
  };

});

因为 firebase .once 方法返回一个 ES6 承诺,所以需要通过将其转换为带有 $q.when$q Service 承诺,将该承诺带入 AngularJS 框架。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

在控制器中,使用.then method提取服务器返回后的数据:

var qPromise = asyncFactory.toController();

qPromise.then(function(data) {
    console.log(data)
    $scope.words = data;
});

工厂函数立即返回一个承诺。当数据从服务器到达时,数据将放在$scope

【讨论】:

    【解决方案2】:

    好吧,toController 正在吃掉自己的承诺。 (当你调用 .then() 时,这意味着你正在等待承诺), 试试这个

    app.factory('asyncFactory', function() {
      let toController = function() {
       var deferred = $q.defer();
        firebase.database().ref('en').once('value') // get the array from the cloud database
        .then(function(snapshot) { // take a snapshot
          console.log(snapshot.val()); // read the values from the snapshot
          return deferred.resolve(snapshot.val()); // this returns later
        });
    
        //return deferred.resolve(47) // this returns immeadiately
      };
    
      return {
        toController: toController // why is this necessary?
      }
    
    });
    

    如果你不想要这条线

    返回{ toController: toController // 为什么这是必要的? }

    app.factory('asyncFactory', function() {
    
      return {
       var deferred = $q.defer();
    
        firebase.database().ref('en').once('value') // get the array from the cloud database
        .then(function(snapshot) { // take a snapshot
          console.log(snapshot.val()); // read the values from the snapshot
          return deferred.resolve(snapshot.val()); // this returns later
        });
    
        //return deferred.resolve(47) // this returns immeadiately
      };
    
    })
    

    【讨论】:

    • 我的控制器正在从工厂返回“未定义”,即它没有等待异步响应。但是感谢您回答我的第二个问题!
    猜你喜欢
    • 2023-03-23
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2016-01-25
    • 1970-01-01
    相关资源
    最近更新 更多