我有以下服务:
function Configuration($http, $q) {
this.$http = $http;
this.$q = $q;
this.promises = [];
this.getEnv().then(function(d) {
this.env = d;
});
}
Configuration.prototype.getEnv = function() {
// only go get the environment setting if we don't already have it
var deferred = this.$q.defer();
if (this.promises.length > 0) {
console.log('%cAdd to queue', 'color:orange;');
this.promises.push(deferred);
} else if (!this.env) {
this.promises.push(deferred);
console.log('%cFetch from live', 'color:red');
// $http returns a promise, which has a then function, which also returns a promise
var promise = this.$http.get('config/env.json').then(function(response) {
// The then function here is an opportunity to modify the response
console.log("environment variable is " + response.data.current_environment);
// The return value gets picked up by the then in the controller.
this.env = response.data.current_environment;
var i;
for (i = this.promises.length; i--;) {
console.log('%cYay! Resolving the existing promises with a single server side request', 'color:white;background:deepskyblue');
this.promises.shift().resolve(this.env);
}
});
} else {
console.log('%cFetch direct from this.env', 'color:green');
deferred.resolve(this.env);
}
// Return the promise to the controller
return deferred.promise;
};
我正在调试我正在构建的promises缓存,以防止多次点击服务器。不幸的是,Chrome中的JS引擎比Apache快得多。这个概念很简单,基本上是在缓存中记录promises,如果方法被命中,如果缓存中没有promise,运行它,如果缓存中有promises,那么就不执行它。
我的问题出现在for (i = this.promises.length; i--;) {
会发生什么是this.promises未定义。我假设它,因为它在嵌套函数内部及其正常的JS变量范围不允许它访问父函数中的变量。但我不确定。
我有办法让这项工作成功吗?
答案 0 :(得分:4)
您可以在this
承诺回调之外缓存$http
,因为在回调中您不再处于服务实例的上下文中: -
var _this = this; //<-- Here
var promise = this.$http.get('config/env.json').then(function(response) {
_this.env = response.data.current_environment;
var i;
for (i = _this.promises.length; i--;) {
_this.promises.shift().resolve(_this.env);
}
});
或者将服务实例的上下文绑定到回调。
this.$http.get('config/env.json').then((function(response) {
// The then function here is an opportunity to modify the response
console.log("environment variable is " + response.data.current_environment);
// The return value gets picked up by the then in the controller.
this.env = response.data.current_environment;
var i;
for (i = this.promises.length; i--;) {
console.log('%cYay! Resolving the existing promises with a single server side request', 'color:white;background:deepskyblue');
this.promises.shift().resolve(this.env);
}
}).bind(this))