AngularJs返回异步工厂?

时间:2017-09-16 21:27:53

标签: angularjs firebase asynchronous angular-promise

我已经阅读了很多这个问题的答案,但我还是没有得到。承诺在哪里?我做了一个简单的工厂,对云数据库进行了异步调用:

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);

以下是回复:

response

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

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

谢谢!

2 个答案:

答案 0 :(得分:1)

to 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
  };

})

答案 1 :(得分: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承诺,所以需要将该承诺带入AngularJS框架,方法是将其转换为$q Service承诺$q.when。只有在AngularJS执行上下文中应用的操作才能受益于AngularJS数据绑定,异常处理,属性监视等。

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

var qPromise = asyncFactory.toController();

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

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