一、初始化数据完成后再加载数据
1、为了达成这个目标尝试了多种方法总是失败
在Init 和didChangeDependencies
初始化数据过也不行
@override void didChangeDependencies() { //getcplist(); WidgetsBinding.instance.addPostFrameCallback((tim) { getcplist(); }); super.didChangeDependencies(); }
尝试使用FutureBuilder 来解决问题,但是要解决FutureBuilder 当调用setstate的时候,将会刷新整个FutureBuilder,结果会是重新请求数据,造成了不必要的请求和资源浪费。
正确的代码如下
class CppageState extends State<Cppage> { @override Widget build(BuildContext context) { return Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: Consumer<CouponProvider>(builder: (context,CouponProvider cplst,Child) { return Column( children: <Widget>[ Container( padding: EdgeInsets.only(top: 5.0,bottom: 10), child: ShowpayWidget(),), Expanded( child: FutureBuilder( future: _futureBuilderFuture, builder: (BuildContext context, AsyncSnapshot snapShot) { if (snapShot.connectionState== ConnectionState.waiting) { return Center(child: Text('Data is Loading...'),); } else if (snapShot.connectionState == ConnectionState.done) { print(snapShot.hasError); print('data:${snapShot.data}');} if (snapShot.hasError) { return Text('Error: ${snapShot.error}'); } return GridView.builder( shrinkWrap: true, itemCount: cplst.couponlst.bfcrmResp.voucherList.length, // physics: NeverScrollableScrollPhysics(),//禁止滚动 padding: EdgeInsets.symmetric(horizontal: 16), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 1, mainAxisSpacing: 10, crossAxisSpacing: 5, childAspectRatio: 4, ), itemBuilder: (context, index) { return Cpitem(cplst.couponlst.bfcrmResp.voucherList[index]); }, ); } ) ) ], ); // ); }) ); } Future getcplist() async { print('xxxxxxxxxxx'); await Provider.of<CouponProvider>(context,listen: false).getCouponlist(); } var _futureBuilderFuture; @override void initState() { print('22222222222'); _futureBuilderFuture =getcplist(); super.initState(); }
二、多网络请求时
其中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
详转自于:https://blog.csdn.net/u013095264/article/details/99977917#_43