这似乎不是执行此操作的正确方法,但它确实有效。是否有一种“rxjs”方式将同步代码转换为异步代码,以便观察者可以在开始处理数据之前返回?我想到的唯一方法是将流程放入Promise中。

@Component({})
export class MyClass {
  public processData() {
    const sub = new BehaviorSubject<number>(0)
    new Promise(() => {
      let c = 0
      let completionPercentage = 0
      for (let x = 0; x < width; x++) {
        for (let y = 0; y < height; y++, c++) {
          // Do some calculations
          // Then compute completion percentage
          sub.next(completionPercentage)
        }
      }
    })
    return sub.asObservable()
  }
}

最佳答案

首先,您当然不应该这样做……并将计算移至BE或服务人员。
但是,如果您这样做了,则应该使用setTimeout / setInterval不要冻结UI。您进行迭代,而不是让Angular检测更改,然后调用另一个迭代。

@Component({
  selector: 'my-app',
  // Most of time browser is busy, though you can click button and see that UI somehow responds
  template: '<button (click)="x = x + 1">test me</button>{{x}}<div *ngFor="let r of results">{{r}}</div>',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  executor = new Executor();
  results = [];
  x = 0;

  ngOnInit(){
    this.executor.subject.subscribe(value => {
      this.results.push(value);
    })
    this.executor.run();
  }

}

class Executor {
  currentRun = 0;
  maxRuns = 1000;
  subject = new Subject();

  run() {
      const r = this.multiply(this.currentRun, this.currentRun);

      this.subject.next(r);
      this.currentRun++;

      if (this.currentRun < this.maxRuns) {
        setTimeout(() => this.run());
      }
  }

   multiply(a, b) {
     const t = new Date().getTime();
     let r = 0;
     for (let i = 0; i < a + 20000; i++) {
       for (let j = 0; j < b + 30000; j++) {
         r++;
       }
     }
     console.log('spent: ' + (new Date().getTime() - t), a, b); // for this time browser is frozen ~ 200-300 ms
     return r;
   }
}

关于javascript - 使同步代码异步以处理大型数组并发出完成百分比,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63984010/

10-11 00:51