我已经阅读了很多这个问题的答案,但我还是没有得到。承诺在哪里?我做了一个简单的工厂,对云数据库进行了异步调用:
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
。稍后异步数据会记录但不会返回控制器。我每天都使用承诺,但我无法弄清楚承诺的去向。
第二个问题:我需要行toController: toController
吗?我可以摆脱它吗?
谢谢!
答案 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
。