List.sort
是一个需要同步回调的同步函数;无法将其与异步回调一起使用。我建议改变你的List
并进行任何必要的异步工作first and then同步对结果进行排序。这样做也应该避免打电话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])
);
(I don't know what the second argument to getItemDistance
represents; if you can't get around that, you would need to build one Map
with getItemDistance(..., true)
results and one with getItemDistance(..., false)
results1.)
作为最后的手段,您可以编写自己的异步排序函数。
Edit #1
这应该是一个更有效的版本,因为它不会一一等待每个异步操作:
final computedDistances = await Future.wait<double>([
for (final item in widget.items) getItemDistance(item, ...),
]);
final computedDistancesMap = <Item, double>{
for (var i = 0; i < widget.items.length; i += 1)
widget.items[i]: computedDistances[i],
};
widget.items.sort((a, b) =>
computedDistancesMap[a].compareTo(computedDistancesMap[b])
);
Edit #2
我添加了一个List.sortWithAsyncKey扩展方法 to package:dartbag可以做到这一点:
await widget.items.sortWithAsyncKey(
(element) => getItemDistance(element, ...),
);
1 However, if you need to call getItemDistance(..., true)
for the first argument and getItemDistance(..., false)
for the second argument, that implies that your comparison function probably is not self-consistent.