一、初始化數據完成后再加載數據
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
