Flutter如何做到网络请求(多个网络请求)完成之后再加载页面

很多时候我们有这样一个需求,需要在网络请求完了之后再去渲染页面,尤其是在一个界面有多个相关网络请求的时候需要处理。
这里不得不提到一个系统的组件FutureBuilder,我们直接来看用法。

FutureBuilder用法

  • 单网络请求:
  • 避免重复网络请求:
  • 多网络请求:
  • 注意事项:
  • 多网络请求如何控制顺序:

单网络请求:

 @overrideWidget buildWidget(BuildContext context, Store store) {// TODO: implement buildWidgetreturn Scaffold(body: FutureBuilder(future: _futureBuilderFuture,builder: (BuildContext context, AsyncSnapshot snapShot) {print('connectionState:${snapShot.connectionState}');if (snapShot.connectionState == ConnectionState.waiting) {return Text('Loading...');} else if (snapShot.connectionState == ConnectionState.done) {print(snapShot.hasError);print('data:${snapShot.data}');if (snapShot.hasError) {return Text('Error: ${snapShot.error}');}return ListView(...

其中第一个参数 future对应的是一个具有Future返回值的方法,这个方法可以是一个网络请求,比如

 Future fetchPost() async {final response = await http.get('http://www.devio.org/io/flutter_app/json/test_common_model.json');Utf8Decoder utf8decoder = Utf8Decoder(); //fix 中文乱码var result = json.decode(utf8decoder.convert(response.bodyBytes));return CommonModel.fromJson(result);}

那我们写法是

  future: fetchPost(),

避免重复网络请求:

但是这样写会有一个问题,那就是当我们调用setstate的时候,将会刷新整个FutureBuilder,结果会是fetchPost这个方法会调用多次,造成了不必要的请求和资源浪费。所以我们建议这样写

  var _futureBuilderFuture;@overridevoid initState() {_futureBuilderFuture = getDatas();super.initState();}

引用的时候

  future: _futureBuilderFuture,

这样当我们调用setstate的时候,就不会有多次网络请求了

下来还有个问题,刚才是界面只有一个网络请求,那么假如有多个呢,写法如下:

  Future getDatas() async {return Future.wait([getDelegationData(), getData()]);}

多网络请求:

其中getDelegationData ,getData是两个单独的网络请求,写法如下

 Future getData() async {var data = {'iReq': "BTC_USDT",};TradeInfo response = await TradeService.getData(this, data.toString());
}

getDelegationData一样,不再给出,这样的话等两个请求都结束之后会返回一个新的Future到我们的FutureBuilder

   if (snapShot.connectionState == ConnectionState.waiting) {return Text('Loading...');} else if (snapShot.connectionState == ConnectionState.done) {print(snapShot.hasError);print('data:${snapShot.data}');if (snapShot.hasError) {return Text('Error: ${snapShot.error}');}

这里的话就用到了snapShot的几种状态,用来判断网络请求处于哪一个阶段,等待(请求中),done完成,包括如果请求有异常的话,我们可以打印出来 return Text(‘Error: ${snapShot.error}’);

注意事项:

这里有一个情况就是我们在调用Future.wait([getDelegationData(), getData()]);的时候,请求网络的顺序是按参数的先后顺序执行的,先走getDelegationData请求,再走getData,但是返回数据结果的顺序却不能保证,因为是根据请求需要的时间决定的,异步的,所以我们尽量把数据处理放在ConnectionState.done之后再处理。

多网络请求如何控制顺序:

另外如果你的网络请求有逻辑关系,比如第一个接口的返回值要当做第二个接口的请求参数,那么写法如下

Future testThen2()  asyn {Future getDatas() async {return getDelegationData().then((e){getData();});}
// 请求顺序是从外层到里层即 getDatas=====getDelegationData===getData

以上over,有不足之处请提出改正


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部