纯CSS旋转器冻结

Pure CSS spinner freezes

本文关键字:冻结 旋转 CSS      更新时间:2023-09-26

我有一个纯CSS微调器,我想显示,而我的JavaScript正在做其他工作(异步调用,然后迭代通过大约10,000个元素的数组)。旋转器会在正确的时间出现,但当触及代码中的某个点时就会冻结。在下面的代码中,"1"、"2"answers"3"的console.log s基本上是立即发生的——然后有一个很长的暂停(这是我的旋转器冻结的时候),然后"4"answers"5"一起退出,我的内容加载。所以基本上我知道" console.log('three') "answers" console.log('four') "之间的代码:

// for search bar
search(text) {
  this.searching = true;  // shows spinner
  console.log('one');
  var text = text.toUpperCase();
  // search the text with an api call
  this.securitiesService.searchSecurities(text)
  .subscribe(data => {
    var response = data.response;
    console.log('two');
    // if no search results are present go to correct page
    if (!response.length) {
      this.router.navigate(...to route...);
      return;
    }
    console.log('three');
    // FREEZES HERE !!!
    for (var i = 0; i < response.length; i++) {
      if (text === response[i].ticker) {
        // UNFREEZES HERE !!!
        console.log('four');
        this.router.navigate(...to route...);
        this.searching = false;
        console.log('five');
        return;
      }
    }
  })
}

我尝试过的每个纯CSS微调器都会出现这种情况。

我认为我的JavaScript不应该冻结我的纯CSS旋转器是错误的吗?为什么代码会冻结它?

JavaScript在UI线程上运行,因此它仍然会阻止仅用于css的旋转器。你需要将工作移出UI线程,或者将其分开,以便UI有时间更新。

根据你需要支持的浏览器,你可以使用Web Workers。请参阅http://caniuse.com/#search=web%20workers获取浏览器支持,或参阅http://www.html5hacks.com/blog/2012/09/22/web-workers-basics-of-the-web-browsers-ui-thread/获取示例。

您还可以一次处理一条(或10条或100条)记录,并将window.setTimeoutwindow.requestAnimationFrame中的每个记录称为"批处理"。试试这样做(代码未测试):

// for search bar
search(text) {
    this.searching = true;  // shows spinner
    console.log('one');
    var text = text.toUpperCase();
    // search the text with an api call
    this.securitiesService.searchSecurities(text)
        .subscribe(data => {
            var response = data.response;
            console.log('two');
            // if no search results are present go to correct page
            if (!response.length) {
                this.router.navigate(...to route...);
                return;
            }
            console.log('three');
            var i = 0;
            var self = this;
            var processBatch = function () {
                if (text === response[i].ticker) {
                    console.log('four');
                    self.router.navigate(...to route...);
                    self.searching = false;
                    console.log('five');
                    return;
                }
                if (++i < response.length) {
                    window.setTimeout(processBatch, 0);
                }
            };
            window.setTimeout(processBatch, 0);
        });
}

如果你想在一个批处理中处理多个项目,你可以在processBatch中设置一个循环,迭代少量的项目。

旁注:如果data.response是字符串,请参阅@gelliott181上面的评论