class UrlProvider {
constructor(root) {
this.root = root;
}
getUrl() {
return this.root + "/api/Situations";
}
}
class Repository {
constructor(urlProvider) {
this.urlProvider = urlProvider;
}
getAsync() {
var self = this;
return httpGetAsync(self.urlProvider.getUrl()).then(function(d) {
return d.map(x => new Situation(x));
});
}
}
class PromiseCacher {
constructor(cache, promise) {
var self = this;
self.cache = cache;
self.promise = promise;
}
runAsync() {
var self = this;
return self.promise().then(function (d) {
self.cache.set(d);
return d;
});
}
}
var urlProvider = new UrlProvider(appsettings.url);
var repository = new Repository(urlProvider);
var cache = new Cache();
var promiseCacher = new PromiseCacher(cache, repository.getAsync);
promiseCacher.runAsync()
调试上面的代码时,chrome会在存储库的getAsync函数内崩溃,因为self.urlProvider未定义。 在存储库内部,getAsync函数'这个'是指PromiseCacher的实例,它实际上是它的名字。
发生了什么?
重新写
var promiseCacher = new PromiseCacher(cache, ()=> repository.getAsync());
让它按照我的预期运作。
答案 0 :(得分:1)
那是因为首先repository.getAsync
不是承诺。相反,它是一个功能。通过将repository.getAsync
的引用存储到不同的对象属性,您可以更改"其this
值。看一下下面的例子:
var obj = {
a: 42,
func: function(){
return this.a;
}
};
obj.func(); // 42
var b = obj.func;
b(); // undefined
该示例与您的代码相似:
class Repository{
// urlProvider = ...
getAsync (){ /* ... */ }
}
var repo = new Repository(/* ... */);
repo.getAsync(); // works
var cacher = new PromiseCacher(/* ... */);
cacher.promise = repo.getAsync;
cacher.promise(); // does not work