异步 Angular Promise 和变量初始化
Asynchronous Angular Promise and Variable Initialization
我有一个看起来像这样的工厂:
app.factory('thingFactory', function($http) {
var factory = {};
var things = [];
factory.refreshThings = function() {
return $http.post('/GetThings');
}
factory.initializeThings = factory.refreshThings()
.then(function(response) {
things = response.data;
}, function(response){
// some error handling code here...
});
factory.getThings = function() {
return things;
}
return factory;
}
和控制器
app.controller('myController', function($scope, thingFactory) {
$scope.things = thingFactory.getThings();
}
由于 promises 的异步性质,以及正在初始化的其他集合(除了 things
),我是否应该关心 getThings()
返回一个空数组,从而在$http.post()
呼叫已解决?
这是更好的选择吗?
app.controller('myController', function($scope, thingFactory) {
$scope.things = []
thingFactory.initializeThings
.then(function(response) {
$scope.things = response.data;
}, function (response) {
// some error handling code here...
});
}
有没有安全的替代方案,我可以让控制器不考虑承诺,而只是安全地从工厂获取集合?
你的代码肯定有问题。工厂在被控制器使用之前不会被实例化,因此 things
在被控制器调用之前不会被初始化,此时 initializeThings
将在您调用 [=14 之前被调用=],这很可能 return 一个空数组。此外,遵循 "let's hope it's there" 方法绝不是一个好主意。
我看到您可以采用两种方法:getThings
接受回调作为参数或者它 return 是一个承诺,它可能看起来像这样:
回调 - 我更喜欢回调而不是承诺,但这是个人的事情。此外,我使用受 NodeJS 启发的语法:
var things; // no need to initialize array
// callback -> function (error, things) {}
factory.getThings = function (callback) {
if (things) {
return callback(null, things);
}
factory.refreshThings()
.then( function (response) {
things = response.data;
return callback(null, things);
}, function (reason) {
return callback(reason);
});
}
Promises - 不是最好的语法,但你明白了
factory.getThings = function () {
var d = $q.defer();
// I'm sure there's a better way to do this, but setting
// this in a timeout will allow the promise to return so that
// you can try to return it.
$timeout( function () {
if (things) {
return d.resolve(things);
}
factory.refreshThings()
.then( function (response) {
things = response.data;
return d.resolve(things);
}, function (reason) {
return d.reject(reason);
});
});
return d.promise;
}
附带说明一下,如果您使用的是 RESTful API,则应使用 GET 获取信息而不是 POST。
我有一个看起来像这样的工厂:
app.factory('thingFactory', function($http) {
var factory = {};
var things = [];
factory.refreshThings = function() {
return $http.post('/GetThings');
}
factory.initializeThings = factory.refreshThings()
.then(function(response) {
things = response.data;
}, function(response){
// some error handling code here...
});
factory.getThings = function() {
return things;
}
return factory;
}
和控制器
app.controller('myController', function($scope, thingFactory) {
$scope.things = thingFactory.getThings();
}
由于 promises 的异步性质,以及正在初始化的其他集合(除了 things
),我是否应该关心 getThings()
返回一个空数组,从而在$http.post()
呼叫已解决?
这是更好的选择吗?
app.controller('myController', function($scope, thingFactory) {
$scope.things = []
thingFactory.initializeThings
.then(function(response) {
$scope.things = response.data;
}, function (response) {
// some error handling code here...
});
}
有没有安全的替代方案,我可以让控制器不考虑承诺,而只是安全地从工厂获取集合?
你的代码肯定有问题。工厂在被控制器使用之前不会被实例化,因此 things
在被控制器调用之前不会被初始化,此时 initializeThings
将在您调用 [=14 之前被调用=],这很可能 return 一个空数组。此外,遵循 "let's hope it's there" 方法绝不是一个好主意。
我看到您可以采用两种方法:getThings
接受回调作为参数或者它 return 是一个承诺,它可能看起来像这样:
回调 - 我更喜欢回调而不是承诺,但这是个人的事情。此外,我使用受 NodeJS 启发的语法:
var things; // no need to initialize array // callback -> function (error, things) {} factory.getThings = function (callback) { if (things) { return callback(null, things); } factory.refreshThings() .then( function (response) { things = response.data; return callback(null, things); }, function (reason) { return callback(reason); }); }
Promises - 不是最好的语法,但你明白了
factory.getThings = function () { var d = $q.defer(); // I'm sure there's a better way to do this, but setting // this in a timeout will allow the promise to return so that // you can try to return it. $timeout( function () { if (things) { return d.resolve(things); } factory.refreshThings() .then( function (response) { things = response.data; return d.resolve(things); }, function (reason) { return d.reject(reason); }); }); return d.promise; }
附带说明一下,如果您使用的是 RESTful API,则应使用 GET 获取信息而不是 POST。