使用 Ramda.js memoize 来缓存 angular2 http 调用
Using Ramda.js memoize in order to cache angular2 http calls
我正在尝试使用 Ramda 的 R.memoize
缓存一个 http 调用,如下所示:
@Injectable()
export class GeolocationService {
private urls;
private cachedAddressAutocomplete;
constructor(private http: HttpClient) {
this.urls = URLS;
this.cachedAddressAutocomplete = R.memoize(input => {
const body = 'address=' + input;
return this.http.get(this.urls.GEOLOCATION.ADDRESS_AUTOCOMPLETE + body).map(res => res.json());
});
}
addressAutocomplete(input: string) {
return this.cachedAddressAutocomplete(input);
}
chooseAddress = (input$: Observable<string>): Observable<string> => {
return input$
.debounceTime(500)
.distinctUntilChanged()
.switchMap(input => input.length < 3 ? [] : this.addressAutocomplete(input));
};
addressFormatter = param => param.description;
}
来自我的调用组件:
@Component({
templateUrl: './signup.component.html',
providers: [FormStatusService]
})
export class SignupComponent implements OnInit {
chooseAddress = this.geolocationService.chooseAddress;
addressFormatter = this.geolocationService.addressFormatter;
...
chooseAddress
被 ng bootstrap 使用如下:
<input type="text"
formControlName="address"
[ngbTypeahead]="chooseAddress"
[inputFormatter]="addressFormatter"
[resultFormatter]="addressFormatter"
autocomplete="off"
class="form-control"/>
但是,我在 chrome 控制台中注意到,即使输入与之前的输入相同,也会始终发出 http/ajax 调用。
有人可以帮忙吗?
我通过将我的 ramda-memoized 函数返回的 http observable 从 cold 转换为 hot 来实现预期的行为,如下所示:
@Injectable()
export class GeolocationService {
private urls;
private cachedAddressAutocomplete;
constructor(private http: HttpClient) {
this.urls = URLS;
this.cachedAddressAutocomplete = R.memoize(input => {
const body = 'address=' + input;
return this.http.get(this.urls.GEOLOCATION.ADDRESS_AUTOCOMPLETE + body)
.map(res => res.json())
.publishLast().refCount();//http is hot now!
});
}
addressAutocomplete(input: string) {
return this.cachedAddressAutocomplete(input);
}
chooseAddress = (input$: Observable<string>): Observable<string> => {
return input$
.debounceTime(500)
.distinctUntilChanged()
.switchMap(input => input.length < 3 ? [] : this.addressAutocomplete(input));
};
addressFormatter = param => param.description;
}
默认情况下,angular2' http 返回的 observable 是冷的。请在此处查看 Thoughtram 博客 post:https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html
通过使用 .publishLast().refCount();
可以使 http Observable hot(而不是默认的 cold)。
现在当输入与上一个相同时,http 调用不会重新发出!
P.S。 如果您有任何建议或意见,请随时评论此答案。
我正在尝试使用 Ramda 的 R.memoize
缓存一个 http 调用,如下所示:
@Injectable()
export class GeolocationService {
private urls;
private cachedAddressAutocomplete;
constructor(private http: HttpClient) {
this.urls = URLS;
this.cachedAddressAutocomplete = R.memoize(input => {
const body = 'address=' + input;
return this.http.get(this.urls.GEOLOCATION.ADDRESS_AUTOCOMPLETE + body).map(res => res.json());
});
}
addressAutocomplete(input: string) {
return this.cachedAddressAutocomplete(input);
}
chooseAddress = (input$: Observable<string>): Observable<string> => {
return input$
.debounceTime(500)
.distinctUntilChanged()
.switchMap(input => input.length < 3 ? [] : this.addressAutocomplete(input));
};
addressFormatter = param => param.description;
}
来自我的调用组件:
@Component({
templateUrl: './signup.component.html',
providers: [FormStatusService]
})
export class SignupComponent implements OnInit {
chooseAddress = this.geolocationService.chooseAddress;
addressFormatter = this.geolocationService.addressFormatter;
...
chooseAddress
被 ng bootstrap 使用如下:
<input type="text"
formControlName="address"
[ngbTypeahead]="chooseAddress"
[inputFormatter]="addressFormatter"
[resultFormatter]="addressFormatter"
autocomplete="off"
class="form-control"/>
但是,我在 chrome 控制台中注意到,即使输入与之前的输入相同,也会始终发出 http/ajax 调用。
有人可以帮忙吗?
我通过将我的 ramda-memoized 函数返回的 http observable 从 cold 转换为 hot 来实现预期的行为,如下所示:
@Injectable()
export class GeolocationService {
private urls;
private cachedAddressAutocomplete;
constructor(private http: HttpClient) {
this.urls = URLS;
this.cachedAddressAutocomplete = R.memoize(input => {
const body = 'address=' + input;
return this.http.get(this.urls.GEOLOCATION.ADDRESS_AUTOCOMPLETE + body)
.map(res => res.json())
.publishLast().refCount();//http is hot now!
});
}
addressAutocomplete(input: string) {
return this.cachedAddressAutocomplete(input);
}
chooseAddress = (input$: Observable<string>): Observable<string> => {
return input$
.debounceTime(500)
.distinctUntilChanged()
.switchMap(input => input.length < 3 ? [] : this.addressAutocomplete(input));
};
addressFormatter = param => param.description;
}
默认情况下,angular2' http 返回的 observable 是冷的。请在此处查看 Thoughtram 博客 post:https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html
通过使用 .publishLast().refCount();
可以使 http Observable hot(而不是默认的 cold)。
现在当输入与上一个相同时,http 调用不会重新发出!
P.S。 如果您有任何建议或意见,请随时评论此答案。