【问题标题】:Pure CSS spinner freezes纯 CSS 微调器冻结
【发布时间】:2017-01-09 14:17:47
【问题描述】:

我有一个纯 CSS 微调器,我想在我的 JavaScript 执行其他工作时展示它(异步调用,然后迭代大约 10,000 个元素的数组)。微调器出现在正确的时间,但在代码中的某个点被击中时会冻结。在下面的代码中,“一”、“二”和“三”的console.logs 基本上立即发生 - 然后有一个长时间的停顿(这是我的微调器冻结时)然后是“四”和“五”一起注销并加载我的内容。所以基本上我知道“console.log('three')”和“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 以查看微调器是否冻结?
  • 所有浏览器都一样吗?可能比较它在不同浏览器中的效率会给你一个视角。
  • 您正在使用 for 循环冻结渲染器。 response.find(x =&gt; x.ticker === text) 会比循环好很多。
  • 查看您的代码,您似乎只希望有一条与条件(text === response[i].ticker) 匹配的记录。在这种情况下,从异步调用返回 10000 条记录不是一种有效的方法。如果你能控制它,更新异步 API 会更好。如果没有,@Brandon 的回复应该会对您有所帮助。

标签: javascript css angular spinner


【解决方案1】:

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.setTimeout 或 window.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 的评论。

【讨论】:

    猜你喜欢
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2014-08-22
    • 1970-01-01
    • 2015-07-02
    相关资源
    最近更新 更多