简体   繁体   English

在打字稿循环结束时回调

[英]callback at the end of a loop in typescript

I'm desperated with this code. 我对这段代码感到绝望。

getSumOfSpecificDayWeek(daysMonth: any, callback: any){
    var data = [];
    var that = this;
    daysMonth.forEach(function(day){
      that.statsService.getData(that.userid, day).subscribe(async (res: any) => {
        data = JSON.parse(JSON.stringify(res));
        console.log(that.data);
        that.data = that.data.map( function(v, i) {
          return v + data[i];
        });
      });
    });
    callback("this should be at the end");
  }

Here what I'm doing is getting arrays from a server and summing it up into that.data per each component of it, this works fine but at the end I want to average the result, at this very moment I'm just calling to callback to show a message to checking whether it occurs finally, but no, "this should be at the end" is displayed before the loop starts summing. 在这里,我正在做的是从服务器获取数组并将其汇总到该组件每个组件的data.data中,这很好,但最后我想对结果取平均,此刻我只是在调用回调以显示一条消息,以检查它是否最终发生,但是不,在循环开始求和之前会显示“这应该在末尾”。

  mycallback(arg: any){
    console.log(arg);
  }

This is the main call to the method 这是该方法的主要调用

this.getSumOfSpecificDayWeek(daysMonth, this.mycallback);

A little more RxJS, but more elegant way: RxJS多一点,但方式更优雅:

getSumOfSpecificDayWeek(daysMonth: any, callback: any){
    var data = [];
    var that = this;
    let getCalls = []; // <--- This will contain all of your observables.
    daysMonth.forEach(function(day){
      const observable = that.statsService.getData(that.userid, day);
      getCalls.push(observable); // <--- Add the current observable to the array.
      observable.subscribe(async (res: any) => {
        data = JSON.parse(JSON.stringify(res));
        console.log(that.data);
        that.data = that.data.map( function(v, i) {
          return v + data[i];
        });
      });
    });
    // And here, you can use `callback`:
    Observable.forkJoin(...getCalls).subscribe(results => {
      callback("this should be at the end");
    });
}

So, this kind of thing is sadly a little confusing in Javascript. 因此,可悲的是,这种事情在Javascript中有点令人困惑。 What this will do is to fire off a request for everything in daysMonth in the background, then call your callback. 这样做是在后台将daysMonth中的所有内容触发一个请求,然后调用您的回调。 The async requests you fired off previously will then complete at some point. 您先前触发的异步请求将在某个时候完成。

Ultimately, what you need to do is to detect when you've done all the work, then fire off your callback. 最终,您需要做的是检测何时完成所有工作, 然后触发回调。 Take a look at something like this instead: 看看这样的东西:

var numDone = 0;

daysMonth.forEach(function(day){
  that.statsService.getData(that.userid, day).subscribe(async (res: any) => {
    numDone++;

    data = JSON.parse(JSON.stringify(res));
    console.log(that.data);
    that.data = that.data.map( function(v, i) {
      return v + data[i];
    });

    if(numDone == daysMonth.length) {
      callback("All done!")
    }
  });
});

Effectively, we can do some work in the getData() callback, and if we're the last thing running, we then call the outer callback with any data we want. 有效地,我们可以在getData()回调中完成一些工作,如果我们正在运行的最后一件事,则可以使用所需的任何数据调用外部回调。

Of course, this can get messy. 当然,这会变得混乱。 The async library abstracts all this quite nicely, so you might be able to use async.map for your purposes too. async库很好地抽象了所有这些,因此您也可以出于自己的目的使用async.map

you need to manage the observable in another way 您需要以其他方式管理可观察对象

you need to execute a array of async operations and then execute a callback function 您需要执行一系列异步操作,然后执行回调函数

your code should look like 您的代码应该看起来像

getSumOfSpecificDayWeek(daysMonth: any, callback: any){
    var data = [];
    var that = this;
    Observable.mergeArray(daysMonth.map(day=> that.statsService.getData(that.userid, day)).subscribe((arrOfResponses)=>{

// do your job with the data 
  callback("this should be at the end"); })


  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM