这似乎不是执行此操作的正确方法,但它确实有效。是否有一种“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/