Какова лучшая практика, чтобы показать прогресс в angulardart? - PullRequest
0 голосов
/ 24 сентября 2018

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

Если я создаю Future, который вызывает себя до тех пор, пока не выполнено условие конца, он работает с индикатором выполнения.Но я думаю, что это не очень хорошая практика, так как эти вызовы будут увеличивать память в стеке при каждой рекурсии.Представьте себе цикл, проходящий через 1 миллиард наборов данных, который может работать несколько часов, и каждый цикл вызывает новое будущее в текущем будущем.

Есть ли лучший способ создать цикл, которому требуется определенное количество времени дляработать над каждым элементом (включая вызов веб-сайта, который должен быть выполнен асинхронным, и оценку возвращаемого значения)?Во время цикла пользователь должен увидеть прогресс, который показывает, что он «x / 1000000 готов».

Я думаю, что это должно быть сделано с Future, поскольку пользовательский интерфейс должен перезагрузиться после запуска цикла, но рекурсивное Future кажетсякак плохая идея для меня.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Тем временем я понял, что метод Future возвращается немедленно, не выполняя ничего в теле метода.Таким образом, решение довольно простое:

Просто объявите RPC с Future, делайте все, что вам нужно сделать в методе, и при вызове его используйте then (...), чтобы сделать то, что вам нужно сделать послесбор данных.

int progress = 0;
int progressMax = 100;
bool progressCanceled = false;

Future rpc(var data)
async{
  for(progress=0; progress<progressMax, progress++)
  {
    // do whatever you need to do with data
    if(progressCanceled)
      return;
  }
}

rpc(data).then(
{
  if(progressCanceled)
    return;
  // do whatever is needed after having received that data
});

rpc выполняется, и вызывающий процесс может продолжаться, пока rpc делает то, что должен делать rpc.Основная программа может обрабатывать нажатия кнопок, чтобы установить для progressCanceled значение true, а метод rpc запросит состояние и прекратит обработку, если оно установлено.

0 голосов
/ 26 сентября 2018

Вам нужно будущее, чтобы сразу вернуться к вам в Интернете, потому что это однопоточная платформа.Если асинхронное действие не вернулось до тех пор, пока оно не было завершено, вы повесили бы браузер, и это не было бы для пользователя большим опытом.

Вместо этого у вас есть несколько вариантов:

У Dart есть возможность сделать так, чтобы будущее выглядело синхронно с ключевым словом await.Таким образом, вы можете сделать что-то вроде:

void performAction() async {
  showProgress = true;
  await expensiveRpc();
  showProgress = false;
}

Это потребует, чтобы прогресс был промежуточным, так как вы фактически не обновляете индикатор выполнения по мере его продвижения.Тем не менее, если вы на самом деле не получаете события прогресса от вашего RPC, возможно, это лучшее решение.

Теперь, если ваш RPC или действие дает вам какую-то обратную связь, вы можете сделать что-то более приятное споток.

void performAction() {
  showProgress = true;
  expensiveRpc().listen((progress) {
    if (progress.done) {
      showProgress = false;
    } else {
      percentComplete = progress.value;
    });
}

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

...