Как использовать List.sort для значений, возвращаемых функцией, которая содержит асинхронный вызов? - PullRequest
1 голос
/ 30 сентября 2019

У меня есть этот код:

 widget.items.sort((a, b) {

           await getItemDistance(a, true);
          await getItemDistance(b, false);

          return (itemADistance)
              .compareTo(itemBDistance);
        });

Я пытаюсь отсортировать список widget.items на основе значений, возвращаемых из getItemDistance. Однако я получаю сообщение об ошибке с красной волнистой линией, которая гласит:

Выражение ожидания можно использовать только в асинхронной функции

и при попытке добавить асинхронную функцию вВ методе сортировки я получаю еще одну красную волнистую линию, которая гласит:

Тип аргумента 'Будущая функция (элемент, элемент)' не может быть назначен типу параметра 'int Function (Item, Item)'

Как мне решить эту дилемму, ребята? :) Спасибо

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

List.sort - синхронная функция, которая ожидает синхронный обратный вызов;нет способа использовать его с асинхронным обратным вызовом. Я бы порекомендовал преобразовать вашу List и выполнить любую необходимую асинхронную работу сначала и , а затем , синхронно сортируя результаты. При этом также следует избегать вызова getItemDistance (который из-за асинхронности может быть дорогостоящим) для одного и того же элемента несколько раз. Например, что-то вроде:

final computedDistances = <Item, double>{};
for (final item in widget.items) {
  final distance = await getItemDistance(item, ...);
  computedDistances[item] = distance;
}

widget.items.sort((a, b) => 
  computedDistances[a].compareTo(computedDistances[b])
);

(я не знаю, что представляет собой второй аргумент getItemDistance; если вы не можете обойти это, вам нужно построить один Map сgetItemDistance(..., true) результатов и один с getItemDistance(..., false) результатами.)

В качестве последнего средства вы можете написать свою собственную функцию асинхронной сортировки.

0 голосов
/ 30 сентября 2019

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

Асинхронные функции возвращают Future, который сообщает дартсу, что в какой-то момент в будущем вы ожидаете itemADistance или ошибку.

Вы захотите вернутьБудущее типа int, так как вы ожидаете получить int itemADistance или ошибку.

   Future<int> widget.items.sort((a, b) async {

                   await getItemDistance(a, true);
                  await getItemDistance(b, false);

                  return (itemADistance)
                      .compareTo(itemBDistance);
                });
...