Javascript 在Angular 8中,如何在固定的时间间隔后调用async方法?

Javascript 在Angular 8中,如何在固定的时间间隔后调用async方法?,javascript,angular,async-await,rxjs,Javascript,Angular,Async Await,Rxjs,我正在调用一个在for循环中运行的API,但我们希望在每次在循环中命中API之前等待1-2秒,因此我们将该方法设置为异步,并在命中API方法之前添加wait 但是我还想每5分钟调用一次异步方法,所以我在关闭异步方法之前添加了interval方法。但它的行为很奇怪,有时会等待5分钟再调用该方法,有时会多次调用,有时会在5分钟结束之前调用。 有什么帮助吗 async fetchData(){ for(let index=0;index<rollNo[].length; index++){

我正在调用一个在for循环中运行的API,但我们希望在每次在循环中命中API之前等待1-2秒,因此我们将该方法设置为异步,并在命中API方法之前添加wait

但是我还想每5分钟调用一次异步方法,所以我在关闭异步方法之前添加了interval方法。但它的行为很奇怪,有时会等待5分钟再调用该方法,有时会多次调用,有时会在5分钟结束之前调用。 有什么帮助吗

async fetchData(){

for(let index=0;index<rollNo[].length; index++){ 

 await new Promise(r => setTimeout(r, 2000)); //delay of 2 sec before passing the next rollNo

//calls the service
  let  subscription = callAPIMethod(rollNo[index]).subscribe((data) => {
  this.Response = data;
  
  subscription.unsubscribe();

}, (error) => {
  this.showToasterMessage('', 'We encountered an error', 'error');
  return;
}); 
}


 //Wait for 5 min before starting all over again
 interval(300000).subscribe(x => {
      this.fetchData();
    });

}
async fetchData(){
for(让index=0;index setTimeout(r,2000));//在传递下一个rollNo之前延迟2秒
//呼叫服务
let subscription=callAPIMethod(rollNo[index])。subscription((数据)=>{
这个。响应=数据;
订阅。取消订阅();
},(错误)=>{
this.showToasterMessage(“”,'我们遇到了一个错误','错误');
返回;
}); 
}
//等待5分钟,然后重新开始
间隔(300000)。订阅(x=>{
这是fetchData();
});
}
在使方法异步之前,我确实尝试了
.pipe(delay(2000))
,但它所做的只是等待2秒钟,然后立即运行整个for循环,这是我不想要的。
Interval或setTimeOut仅在方法不异步时才起作用,但如果我没有将该方法设置为异步,那么我就不能在每次点击API之前等待2秒钟。

确保可以使用另一种方法和计时器rxjs/操作符来获取它。可观察到的相似物

obs=timer(0,1000).pipe(
      take(this.rollNo[].length),
      switchMap(_=>{
      return callAPIMethod()
    }))
如果你在另一个计时器内使用水龙头

timer(0,30000).pipe(switchMap(_=>{
  return this.obs.pipe(tap((res)=>{
      this.Response=res;
  }))
})).subscribe()
你明白了

更新我在年做了一个“傻瓜榜样”。您可以看到可观察的“callAPIMethod”是如何被多次调用的,因为每秒钟元素都有数组“values”,10秒后再次启动(实际上是“values”有4个元素,大约7秒后)

更新2您的代码如下

//this NOT WORK, callAPIMethod return null
//in general, when we work with observables only makes actions in subscribe or in tap 
//in the main "subscription" -in the example I use tap because I want to 
//execute actions in a "inner observable"
callAPIMethod(code) {
    let subscription = this.appService
      .slotByPin(code, this.date)
      .subscribe(data => {
        this.response = data;
        this.someOperationInsideThisMethod();
        subscription.unsubscribe();
      });
  }
但是您应该转换,您的callAPIMethod应该返回一个可观察的,所以通过

this.obs = timer(0, 1000).pipe(
  take(this.parameters.length),
  switchMap(index => {
    //see that index is the result of "timer", that's 0,1,2,3...
    //so we can send to the callAPIMethod parameters[index]
    return this.callAPIMethod(parameters[index]);  
  })
);
timer(0, 10000)
      .pipe(
        switchMap(_ => {
          return this.obs.pipe(
            tap(
              data => {
        //see that you put here the code you had in your "callAPIMethod"
        this.response = data;
        this.someOperationInsideThisMethod();
            })
          );
        })
      )
      .subscribe();
  
  //see how the "callAPIMethod" return an observable
  callAPIMethod(code) {
    return this.appService
      .slotByPin(code, this.date)
      
  }
解决了这个问题

selectedCodes: string[] = [];

 ngOnInit() {
this.delayedLoop(this.selectedCodes.length, 0);


setInterval(() => {
  this.initializeSearch();
  this.delayedLoop(this.selectedCodes.length, 0);
}, ((5000+this.selectedCodes.length)*1000));


  delayedLoop(i:any,pIndex:any) {
    let arrLength =  i;
    let tempIndex = pIndex;
    if(this.selectedCodes && pIndex <  this.selectedCodes.length){
      let myThis = this;
      setTimeout(function() {
        myThis.fetchSlots(tempIndex,this.dateArrray);  
       
        if (--arrLength) {
          tempIndex++;
          myThis.delayedLoop(arrLength,tempIndex);
        }  
      }, 1000)
    }
  }
selectedcode:string[]=[];
恩戈尼尼特(){
this.delayedLoop(this.selectedCodes.length,0);
设置间隔(()=>{
这是.initializeSearch();
this.delayedLoop(this.selectedCodes.length,0);
},((5000+此.selectedCodes.length)*1000));
延迟循环(i:any,pIndex:any){
设arrLength=i;
设tempIndex=pIndex;
if(this.selectedCodes&&pIndex
顺便说一句,如果您正在搜索如何在线执行此操作,请在搜索词中包含
rxjs
,因为这是angular用于异步调用和操作的库。为什么这个问题已结束?上面提到的问题没有回答我提出的问题。请参阅副本中的答案(仅接受的答案之外)它们包括如何创建一个重复出现的计时器来做某事(你的5分钟),而你已经有了延迟(2秒)。您可以将其全部放在一个操作中,而不是两个调用中,但如何抽象调用取决于您。请阅读问题。所有这些答案都是针对普通方法的,而不是异步方法。我想在某个时间间隔后再次调用异步方法,但该方法无法正常工作。请关闭问题,因为存在类似的情况r是不公平的。你可以做
interval(300000)。pipe(delay(2000)).subscribe(()=>callAPIMethod().subscribe())
。但其中一个问题是你把rxjs与promise混用/匹配,这可能会导致诸如不等待结果之类的错误。对不起,我没有理解你。我的callAPIMethod()接受for循环的参数,本质上是这样的。rollNo[index]。我现在如何传递索引?请正确回答,我不明白您要我在哪里编写这两个方法。for循环或main方法中的所有内容?我用“傻瓜堆栈闪电”更新了答案,我希望这在某种程度上有助于理解代码是的,但在第一个方法中,您甚至没有订阅callAPIMethod(),也没有将其值存储到结果数组中。可能我错了,但您只是在第二个方法中这样做。我对吗?我做错了什么?请帮助我更正它