面试题答案
一键面试- Stream的创建:
- 在Flutter中,可以使用
StreamController
来创建一个Stream
。例如,如果要模拟股票价格变动数据的推送,可以这样创建:
final _stockPriceController = StreamController<double>(); Stream<double> get stockPriceStream => _stockPriceController.stream;
- 这里创建了一个
StreamController
,它可以控制一个Stream
,stream
属性暴露了这个可监听的Stream
。在实际应用中,数据可能从服务器获取,例如使用HTTP请求结合dart:async
库来定期获取数据并通过StreamController
添加到Stream
中。
- 在Flutter中,可以使用
- 监听Stream:
- 使用
Stream
的listen
方法来监听数据。例如:
stockPriceStream.listen((price) { print('Current stock price: $price'); // 这里可以进行UI更新等操作,如更新股票价格显示 });
listen
方法接受一个回调函数,每当Stream
有新数据时,这个回调函数就会被调用。
- 使用
- 错误处理:
listen
方法还可以接受一个onError
回调函数来处理Stream
产生的错误。例如:
stockPriceStream.listen((price) { print('Current stock price: $price'); }, onError: (error) { print('Error occurred: $error'); // 可以在这里进行错误提示等处理,比如显示一个错误弹窗给用户 });
- 当
Stream
出现错误时,onError
回调函数会被调用,这样可以及时捕获并处理异常情况。
- 背压策略的应用:
- 什么是背压:当
Stream
产生数据的速度比监听者处理数据的速度快时,就会出现背压问题。例如,服务器推送股票价格变动数据非常频繁,而UI更新操作相对较慢,就可能出现背压。 - 解决方案:
- Buffering:可以使用
StreamTransformer
的buffer
方法。例如:final bufferedStream = stockPriceStream.transform(StreamTransformer.fromHandlers( handleData: (data, sink) { sink.add(data); }, )).buffer(10); bufferedStream.listen((prices) { // 这里的prices是一个包含10个数据的列表,一次性处理一批数据 print('Buffered stock prices: $prices'); });
buffer
方法可以设置一个缓冲区大小,Stream
的数据会先进入缓冲区,当缓冲区满时,再一次性传递给监听者,这样可以减少处理频率,提高性能。
- Dropping:使用
StreamTransformer
的drop
方法。例如:final droppedStream = stockPriceStream.transform(StreamTransformer.fromHandlers( handleData: (data, sink) { sink.add(data); }, )).drop(5); droppedStream.listen((price) { // 这里会丢弃前5个数据,从第6个数据开始处理 print('Dropped stock price: $price'); });
drop
方法可以丢弃一定数量的数据,适用于在数据量较大且早期数据相对不重要的场景,以避免处理过多无用数据导致性能问题。
- Buffering:可以使用
- 什么是背压:当
通过以上步骤,可以在Flutter中使用Stream
有效地处理服务器推送的实时数据,如股票价格变动,确保性能不受影响。