如何对从包含异步的函数返回的值使用 List.sort?
Posted
技术标签:
【中文标题】如何对从包含异步的函数返回的值使用 List.sort?【英文标题】:How to use List.sort on values returned from a function that contains an async? 【发布时间】:2020-01-29 06:38:28 【问题描述】:我有这个代码:
widget.items.sort((a, b)
await getItemDistance(a, true);
await getItemDistance(b, false);
return (itemADistance)
.compareTo(itemBDistance);
);
我正在尝试根据从 getItemDistance 返回的值对 widget.items 列表进行排序。但是,我收到一条红色波浪线错误,上面写着:
await 表达式只能在异步函数中使用
当我尝试将异步添加到排序方法时,我得到另一条红色波浪线:
无法分配参数类型“Future Function(Item, Item)” 到参数类型'int Function(Item, Item)'
我该如何解决这个难题? :) 谢谢
【问题讨论】:
【参考方案1】:每当您运行异步代码时,您都应该添加如下所示的 async 关键字。这告诉 dart 你打算运行异步代码。
异步函数返回一个 Future,它告诉 dart 在未来的某个时间点你期待 itemADistance 或一个错误。
您将希望返回 int 类型的 Future,因为您希望收到 int itemADistance 或错误。
Future<int> widget.items.sort((a, b) async
await getItemDistance(a, true);
await getItemDistance(b, false);
return (itemADistance)
.compareTo(itemBDistance);
);
【讨论】:
您好帕特里克,感谢您的及时答复。但是,当我尝试此代码时,出现此错误:无法将参数类型“Future Function(Item, Item)”分配给参数类型“int Function(Item, Item)” 如果您以后使用 return 关键字,您应该告诉 dart 您希望将来收到什么类型。如果您没有返回任何内容,请告诉它 FutureList.sort
是同步的,并且需要一个同步回调(即,一个返回 int
,而不是 Future<int>
的函数)。它不能与异步回调一起使用。【参考方案2】:
List.sort
是一个同步函数,需要一个同步回调;无法将它与异步回调一起使用。我建议您转换您的 List
并执行任何必要的异步工作first 和 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])
);
(我不知道getItemDistance
的第二个参数代表什么;如果您无法解决这个问题,则需要构建一个带有getItemDistance(..., true)
结果的Map
和一个带有getItemDistance(..., false)
结果的Map
。 )
作为最后的手段,您可以编写自己的异步排序函数。
编辑
这应该是一个更高效的版本,因为它不会一个接一个地等待每个异步操作:
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])
);
【讨论】:
以上是关于如何对从包含异步的函数返回的值使用 List.sort?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Select2.js 对从 Ajax 调用返回的数据进行多选结果?