Как заполнить массивы эффективно и без блокировки

Как заполнить массивы эффективно и без блокировки

05.01.2020 04:13:23 Просмотров 33 Источник

Сценарий выглядит следующим образом...

Шаблон компонента

<template>
  <div>
   <loader v-show="loading"></loader> // loading animation
   <div v-show="!loading">
     <div v-for="group in groups">
       {{group.name}}
       <div v-for="item in group.list">
         {{item.name}}
       </div>
     </div>
   </div>
  </div>
</template>

Данные компонентов

data: function () {
    return {
        list: [],
        groups: [],
        loading: true
    }
}

1. извлечение 1 мерного массива из api

axios.get(API_URL).then(
    (response) => {
        this.list = response.data.payload;
    }
);

Структура массива выглядит следующим образом...

[
  {
    "name": "bob",
    "group": "A"
  },
  {
    "name": "sally",
    "group": "A"
  },
  {
    "name": "john",
    "group": "B"
  },
  {
    "name": "jane",
    "group": "B"
  },
]

2. преобразование массива в 2 измерения с помощью свойства group каждого элемента

текущее решение (блокировка!- неэффективно?)

// loading animation stops at this point
this.list.forEach((item, index) => {
    let hasGroupChanged = false;
    if (index === 0) {
        hasGroupChanged = true;
    } else {
        let currentGroupName = item.group;
        let previousGroupName = this.list[index - 1].group;
        hasGroupChanged = previousGroupName !== currentGroupName;
    }
    if (hasGroupChanged) {
        const group = {
            group: item.group,
            list: []
        };
        this.groups.push(group);
    }
    const groupIndex = this.groups.length - 1;
    this.groups[groupIndex].list.push(item);
});

this.loading = false;

как сохранить анимацию загрузки до тех пор, пока группы не будут заполнены?

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/59600232/how-to-populate-arrays-efficiently-and-non-blocking#comment105364763_59600232
Вам нужен способ эффективного заполнения массивов или вы хотите обеспечить запуск анимации загрузки до тех пор, пока вы не загрузите данные? Поддерживает ли ваше текущее решение анимацию загрузки до конца? Что делает ваше текущее решение блокирующим?

Ответы - Как заполнить массивы эффективно и без блокировки / How to populate arrays efficiently and non blocking

forkerino

05.01.2020 04:30:23

Я предполагаю, что проблема заключается в том, что вы устанавливаете loading в false до того, как axios закончит получать ваши данные (потому что это единственная асинхронная операция в коде).

Тот самый .forEach, вероятно, можно было бы немного оптимизировать, но я сомневаюсь, что это виновник.

Попробуйте переместить весь ваш код в поле .then приковал от axios.get() вместо этого.

Andre Nuechter

05.01.2020 04:56:25

Я действительно не могу говорить об эффективности вашего кода, но простой способ сохранить индикатор загрузки до завершения асинхронной операции-это остановить его в finallyблоке:

const btn = document.getElementById('btn');
const mockLoadIndicator = document.getElementById('loading');
const data = [
  {
    "name": "bob",
    "group": "A"
  }, {
    "name": "sally",
    "group": "A"
  }, {
    "name": "john",
    "group": "B"
  }, {
    "name": "jane",
    "group": "B"
  }
];
const mockAPI = () => {
  mockLoadIndicator.style.display = 'block';
  return new Promise((resolve) => {
    setTimeout(() => resolve(data), 1000);
  });
};

btn.onclick = () => mockAPI()
.then(console.log)
.finally(() => {
  mockLoadIndicator.style.display = 'none';
});
#loading {
  position: relative;
  display: none;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background: grey;
  animation-duration: 300ms;
  animation-name: load;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@keyframes load {
  from {
    left: 10px;
  }
  to {
    left: 40px;
  }
}
<button id="btn">Get Data</button>
<div id="loading"></div>

Michal Levý

05.01.2020 05:02:01

Ваша анимация "загрузки" "заморожена", потому что JavaScript является однопоточным, и когда ваш код преобразования выполняется (предполагая, что существует гораздо больше данных, чем показано в Примере, поэтому он выполняется в течение значительного времени), визуализация браузера блокируется.

Либо вы можете оптимизировать код преобразования, чтобы сделать его быстрее, либо вы можете взглянуть на это, поэтому ответьте за детали и решения, как сделать длительные операции, чтобы не блокировать рендеринг браузера....

Закрыть X