一、初始化数据完成后再加载数据

 1、为了达成这个目标尝试了多种方法总是失败

在Init 和didChangeDependencies

初始化数据过也不行

  @override
  void didChangeDependencies() {
    //getcplist();
        WidgetsBinding.instance.addPostFrameCallback((tim) {
         getcplist();
    });
    super.didChangeDependencies();
  }
View Code

尝试使用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();
  }
View Code

二、多网络请求时

其中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

 

posted on 2019-12-09 15:57  EEEEEEEEEEEEEEEEEEE  阅读(8031)  评论(0编辑  收藏  举报