【发布时间】:2016-04-19 20:06:51
【问题描述】:
我需要在第一次调用时缓存请求的结果,然后为后续调用读取缓存值。
为了实现这个目标,我正在使用 Promise 并将它们链接起来。我有一个可行的解决方案,但我想将其转换为 RxJS 的 observables 而不是 Promises。
这是我的工作解决方案:
private currentPromise: Promise<{ [key: string]: any }>;
private cache: any;
public getSomething(name: string): Promise<number>{
return this.currentPromise = !this.currentPromise ?
this._getSomething(name) :
new Promise((r) => this.currentPromise.then(() => this._getSomething(name).then((res) => r(res))));
}
private _getSomething(name: string): Promise<any> {
return new Promise((resolve) => {
if (this.cache[name]) {
this.messages.push("Resolved from cache");
resolve(this.cache[name]);
} else {
// Fake http call. I would use Angular's Http class.
setTimeout(()=> {this.messages.push("Resolved from server"); this.cache[name] = name; resolve(this.cache[name]); }, 2000 );
}
});
}
this.getSomething("thing1").then((res)=>this.messages.push(res));
this.getSomething("thing1").then((res)=>this.messages.push(res));
this.getSomething("thing2").then((res)=>this.messages.push(res));
this.getSomething("thing2").then((res)=>this.messages.push(res));
this.getSomething("thing1").then((res)=>this.messages.push(res));
this.getSomething("thing2").then((res)=>this.messages.push(res));
this.getSomething("thing1").then((res)=>this.messages.push(res));
this.getSomething("thing2").then((res)=>this.messages.push(res));
你可以在这个 plunkr 上测试它:https://plnkr.co/edit/j1pm2GeQf6oZwRvbUsXJ?p=preview
如何使用 RxJS 5 beta 实现相同的目标?
更新
按照 Bergi 的 cmets,我更新了我的 plunkr 和我的代码,使其更接近我的真实案例
【问题讨论】:
-
"
new Promise((r) => this.currentPromise.then(() => this._getSomething(params).then((res) => r(res))));" - 什么?这应该做什么(和:don't do it)?为什么不直接返回currentPromise? -
如果您已经缓存了
currentPromise,则无需额外缓存.cache中的值本身。不要过于复杂。 -
@Bergi 每次调用“getSomething”时,我都会在 currentPromise 中附加一个新的“.then()”,因此所有“getSomething”调用都按照它们被调用的顺序执行。第一个调用从服务器获取数据并缓存它。随后的调用从缓存中返回数据。
-
您不需要多次执行它们 - 您已经在
currentPromise中获得了第一次调用的(承诺)结果。您可以简单地多次返回它。它将按照它们被隐式附加的相同顺序调用所有回调。 -
我在现实世界的情况下,每次都必须调用 _getSomething,因为“params”可以改变结果。我的缓存实际上是一个字典。因此,如果我调用 getSomething("thing1") 它将检查“thing1”是否已经在缓存中,如果没有,它将调用服务器。
标签: javascript typescript promise rxjs rxjs5