需求:要在本地实现数据搜索,在数据量超大的情况下遍历搜索可能非常耗时,考虑使用Isolate避免造成页面卡顿
实现:
_searchText为输入字符
dataModule.dataList为数据源List
void doSearchWork() async {
await isolateSearchEven(_searchText, dataModule.dataList)
.then((value) => print(value));
}
///使用isolate的方式封装耗时操作
static Future<dynamic> isolateSearchEven(
String searchKey, List allData) async {
final p = ReceivePort();
///发送参数
await Isolate.spawn(_entryPoint, [p.sendPort, searchKey, allData]);
return (await p.first) as List;
}
static void _entryPoint(List<dynamic> args) {
SendPort responsePort = args[0];
String key = args[1];
List data = args[2];
///接收参数,进行耗时操作后返回数据
responsePort.send(getSearchResults(key, data));
}
//耗时操作
static List getSearchResults(String searchStr, List data) {
if (searchStr.isEmpty) {
return [];
}
List<List<Map<int, int>>> results = [];
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (item is Map) {
List<Map<int, int>> rowList = [];
var j = 0;
for (var key in item.keys) {
var temp = item[key] is String ? item[key] : item[key].toString();
if (temp.contains(searchStr)) {
Map<int, int> row = {};
row[i] = j;
rowList.add(row);
}
j++;
}
if (rowList.isNotEmpty) {
results.add(rowList);
}
}
}
return results;
}
测试结果:
上面的方法需要声明static,测试发现不用static未报错,但是也不会返回结果。
观察堆栈可以看到每次Isolate调用返回结果集后自行关闭了,资源应该也得到了释放。但是在连续输入字符的时候会触发多个Isolate,每个Isolate都会返回一次结果,可能会占用大量资源,存在性能隐患。