使同步代码异步以处理大型数组并发出完成百分比

问题描述

这似乎不是正确的方法,但确实有效。是否有一种“ 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;
   }
}
,

请考虑将Subject替换为ConnectableObservable并与publishReplay运算符结合使用,以便您的Observable立即开始运行,而以后的订阅者可以访问先前发出的值(感谢{ {1}}运算符),使用publishReplay可确保您的代码将异步运行。

timer(0)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...