使用Ramda.js memoize来缓存angular2 http调用

时间:2017-03-19 17:08:33

标签: angular rxjs ramda.js

我正在尝试使用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;
  ...
ng bootstrap使用

chooseAddress,如下所示:

 <input type="text"
         formControlName="address"
         [ngbTypeahead]="chooseAddress"
         [inputFormatter]="addressFormatter"
         [resultFormatter]="addressFormatter"
         autocomplete="off"
         class="form-control"/>

但是,我注意到在chrome控制台中,即使输入与前一个输入相同,也始终会发出http / ajax调用。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

我设法通过将我的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很冷。请参阅这里的[@ 3}}

使用.publishLast().refCount();可以使http Observable (默认情况下代替)。

现在,当输入与前一个输入相同时,不会重新发出http调用!

P.S。 如果您有任何建议或评论,请随时评论此答案。