Неблокирующий интерфейс во время операций поиска / сортировки / фильтрации - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть большой список предметов (3000 - 5000) для отображения. Пользователь может фильтровать / сортировать их, чтобы отображать только конкретное подмножество. Моя первоначальная реализация была по существу:

import { filterItems, sortItems }

const items = [...];
const results = flow([
  filterItems,
  sortItems,
])(items);

... где импортируемые функции в основном являются обертками вокруг массива .sort и .filter (+ множество пользовательских опций). Это работает, но блокирует пользовательский интерфейс. Я ищу рекомендации о том, как действовать, все еще используя эти две основные функции. Я чувствую, что у меня есть два основных пути:


1) JS планирование / срезание времени

Как можно разбить функции фильтра / сортировки, чтобы приспособиться к этому? Я пытался использовать что-то вроде планировщика очереди + , слегка модифицируя sortItems, чтобы получить каждый l oop, но, как все это происходит в обратном вызове sort, он делает не работает:

// simplified for brevity
function sortItems(items, context) { // context comes from a Scheduler
  return items.sort((a, b) => {
    context.yield();                 // can I return control back here ...?
    return (+!a - +!b) || (a > b ? 1 : -1);
  }
}

Я хочу попробовать другие варианты здесь на эту тему (ie. setTimeout, rAF et c), но так как здесь нет функции «единица работы» или «шаг» Мне интересно, нужно ли мне реализовать собственную сортировку / фильтрацию, используя for l oop, а не полагаться на [].filter / [].sort. Есть ли последствия для производительности?


2) Веб-работник

Это еще один вариант. Однако для удобства обслуживания я бы предпочел повторно использовать filterItems, sortItems без необходимости копировать / вставлять их в рабочий файл. Есть ли способ сделать это? Я знаю, как встроить работника, т. Е. Использовать URL + Blobs или Greenlet ... но я не смог заставить его работать.

let results = greenlet(async (items) => {
  const filtered = filterItems(items); // <-- i realize this is not possible (and doesn't work)
  ...
});

Похоже - is Можно ли как-то использовать импортированную функцию через toString() в работнике? то есть filterItems.toString() + метод встраивания?


Если у вас есть общий совет или вы можете поделиться опытом в подобных предприятиях (или если я делаю это неправильно), пожалуйста, дайте мне знать. Заранее спасибо ~

...