Javascript 如何使用rxjs进行自动保存?

Javascript 如何使用rxjs进行自动保存?,javascript,angular,rxjs,Javascript,Angular,Rxjs,根据这些标准,如何使用rxjs进行自动保存 单击save按钮应该发出http请求来保存我的数据(来自局部变量,而不是表单) 每3000ms(间隔)应该像我点击按钮一样 无法创建并行http请求。在请求激活之前,另一个请求在完成之前不应运行。如果请求是begin,那么所有其他请求都应该在队列中等待(然后逐个执行) 保存按钮在队列/执行中应具有高优先级 我想使用rxjs的强大功能,因此最好使用rxjs操作符而不是局部变量(if(this.requestStart==true)) 这是我想要达到的

根据这些标准,如何使用
rxjs
进行自动保存

  • 单击save按钮应该发出http请求来保存我的数据(来自局部变量,而不是表单)
  • 每3000ms(间隔)应该像我点击按钮一样
  • 无法创建并行http请求。在请求激活之前,另一个请求在完成之前不应运行。如果请求是begin,那么所有其他请求都应该在队列中等待(然后逐个执行)
  • 保存按钮在队列/执行中应具有高优先级
我想使用rxjs的强大功能,因此最好使用rxjs操作符而不是局部变量(
if(this.requestStart==true)

这是我想要达到的目标。任何帮助都将不胜感激

import { Component, Input } from '@angular/core';
import {Observable, interval} from 'rxjs';

@Component({
  selector: 'hello',
  template: `

  <h1>Hello {{name}}!</h1>
  <button (click)="save()">save</button>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input() name: string;

  constructor() {
    interval(3000)
      .subscribe(val => this.makeRequest());

  }

  save() {
    this.makeRequest().subscribe(res => {
      console.log({ res });
    });
  }

  makeRequest() {
    return Observable.create((observer) => {
      setTimeout(() => {
        observer.next({ save: true });
        observer.complete();
      }, 5000);
    });
  }
}
从'@angular/core'导入{Component,Input};
从“rxjs”导入{observatable,interval};
@组成部分({
选择器:“你好”,
模板:`
你好{{name}}!
拯救
`,
样式:[`h1{font-family:Lato;}`]
})
导出类HelloComponent{
@Input()名称:string;
构造函数(){
间隔(3000)
.subscribe(val=>this.makeRequest());
}
保存(){
this.makeRequest().subscribe(res=>{
console.log({res});
});
}
makeRequest(){
返回可观察的。创建((观察者)=>{
设置超时(()=>{
下一步({save:true});
observer.complete();
}, 5000);
});
}
}

您可以使用
合并
排气图
来确保一次只处理一个请求

比如:

// Get a btn reference
const btnEl = document.getElementById('send-btn');

merge(
  fromEvent(btnEl, 'click'),
  interval(3000)
).pipe(
  concatMap(_ => this.makeRequest())
)
.subscribe(res => {
  console.log({ res });
});

要实现优先级划分并不容易,
rxjs
并不是在这个意义上围绕排队构建的

在这种情况下,您可以使用
switchMap
concatMap

manualSave$ = new Subject<any>();

constructor(private http: HttpClient) { }

ngOnInit() {
  this.manualSave$.pipe(
    switchMap(() => timer(0, 3 * 1000)),
    concatMap(() => this.makeRequest())
  ).subscribe(result => {
    console.log(result);
  })
  this.manualSave$.next(); // to start it off
}

save() {
  this.manualSave$.next();
}

makeRequest() {
  const url = 'https://jsonplaceholder.typicode.com/todos/1';
  return this.http.get(url);
}
与合并相比,我更喜欢使用
switchMap
,因为
merge
可以:

---1----2----3----4----5----6---...
-----X--------X-------------X---...
      merge
---1-X--2----3X---4----5----(6X)...
---1----2----3----4----5----6---...
-----X--------X-------------X---...
      switchMap
---1-X----2---X----4----5---X---...
switchMap
会取消以前的值并执行以下操作:

---1----2----3----4----5----6---...
-----X--------X-------------X---...
      merge
---1-X--2----3X---4----5----(6X)...
---1----2----3----4----5----6---...
-----X--------X-------------X---...
      switchMap
---1-X----2---X----4----5---X---...

仅发出必要数量的请求。

如果在makerequest完成之前发生,您将丢失源事件,这可能不是Jon想要的。我使用
concatMap