如何阻塞 UI 直到所有未决操作完成?

How to block UI until all pending operations are complete?

我有一个带有 NgxSpinner 的 Angular 8 网络应用程序。当一些冗长的过程正在进行时,我用它来阻止 UI 以防止用户在某些部分尚未完全加载时与复杂的表单进行交互。

问题在于,如果某些进程调用 hide,NgxSpinner 会立即隐藏自己,无论是否还有另一个进程具有自己的 show/hide 调用对 运行。因此,当任何较短的进程已完成并调用 spinner.hide().

时,网页过早解锁

这是 Stackblitz 示例。

如何让 NgxSpinner 等待最后一个 hide 匹配所有 show 调用?

P.S。这似乎是我尝试过的许多 UI 块库的问题 - 它们只是不考虑多次调用 show/hide 的并行进程。

你可以使用 Promise。每个 Process 函数都会 return 一个承诺,然后您可以使用 Promise.all 函数,一旦所有承诺都得到解决,该函数就会被调用。您可以在 promise.all 方法中隐藏微调器。 请在下面找到示例代码。

this.spinner.show();
let p1 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

let p2 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

Promise.all([p1,p2]).then( ()=> {
  this.spinner.hide();
})

您可能想要使用 forkJoin 运算符,在这种情况下,您将在所有请求完成后进入此状态,然后您将隐藏您的加载微调器

为微调器创建一项服务并在那里保持 show/hide 计数。

export class MySpinnerService {
  showIndex = 0;
  hideIndex = 0;

  constructor(private spinner: NgxSpinnerService) {}

  show() {
    this.showIndex++;
    this.spinner.show();
    console.log('show spinner', this.showIndex);
  }

  hide() {
    this.hideIndex++;
    if (this.showIndex === this.hideIndex) {
      this.spinner.hide();
      console.log('hide spinner', this.hideIndex);      
    }
  }

所以当 showIndexhideIndex 相等时,您需要隐藏微调器。

调用你的组件

this.mySpinner.show(); // show spinner
this.mySpinner.hide(); // hide spinner

这是 Stackblitz 中的示例。