[Flutter Async]-异步

事件循环Event Loop机制

Future就像是盒子里的巧克力糖

http.get("www.baidu.com").then((value) => null).catchError(onError);
//http.get("www.baidu.com")	Future刚建成没有完成的状态
//then((value) => null)		正常完成后得到一个值的状态
//catchError(onError)	异常完成后得到一个错误信息的状态
Future<String> getFuture() {
    return Future(() => "alice");
    //return Future.delayed(Duration(seconds: 2), () => "alice");
}
//----------------------------------------
getFuture().then((value) => print(value)); //then是future完成后要做的操作
Future<String> getFuture() {
    return Future(() => "alice");
}
//----------------------------------------
getFuture().then((value) => print(value)); //then是future完成后要做的操作
print('hi');
/*
hi
alice
*/
//因为future会被放到Event Queue里,等Main里的操作执行完才会执行EventQueue里的
void main() {
    //event queue,等main执行完,再执行microtask,然后再执行event queue里的任务
    Future(() => print('event 1'));
    Future.delayed(Duration(seconds: 1), () => print('event 2'));

    //microtask会员区,main运行完就会优先运行microtask里的任务
    scheduleMicrotask(() => print('microtask 1'));
    Future.microtask(() => print('microtask 2'));
    Future.value(123).then((value) => print("microtask 3")); //_completed.then()

    //直接运行
    print("main1");
    Future.sync(() => print('sync 1'));
    Future.value(getName());
    print('main 2');
    Future.delayed(Duration(seconds: 1), () => print('delayed')).then((value) {
        print('then');
        scheduleMicrotask(() => print('micro'));
    }).then((value) => print('then2'));    //_.then

    runApp(MyApp());
}

捕获异常

//用法1
Future<String> getFuture() {
    return Future.error(Exception("someting went wrong"));
}
//------------------------------------------------------------
getFuture()
    .then((value) => print(value))
    .catchError((err) => print(err))
    .whenComplete(() => print('completed'));


//用法2
Future<int> getFuture() async {
    throw "oops";
}
//---------------------------------
void _incrementCounter() async {
    try {
        int d = await getFuture();
    } catch (err) {
        print(err);
    }

    setState(() {
        _counter++;
    });
}

Chain

Future<int> getFuture() {
    return Future.value(100);
}
//----------------------------------
getFuture()
    .then((value) {
        print(value);
        return value * 2;
    })
    .then((value) => print(value))
    .catchError((err) => print(err))
    .whenComplete(() => print('completed'));
/*
I/flutter (12124): 100
I/flutter (12124): 200
I/flutter (12124): completed
*/

async and await

Future<int> getFuture() async {
    return 100;
}
//--------------------------------
void _incrementCounter() async {
    int d = await getFuture();
    print(d);
    d = d * 2;
    print(d);

    setState(() {
        _counter++;
    });
}
/*
I/flutter (12124): 100
I/flutter (12124): 200
*/

深入了解FutureBuilder组件

Center(
    child: FutureBuilder(
        future: Future.delayed(Duration(seconds: 2), () => throw ('oops')),
        //initialData: 72, //初始值
        //snapshot是future最近的状态
        builder: (context, snapshot) {
            //等待
            // if(snapshot.connectionState==ConnectionState.waiting){}
            //完成
            // if(snapshot.connectionState==ConnectionState.done){}
            
            //有错误
            if (snapshot.hasError) {
                return Icon(Icons.error, size: 80);
            }
            //有数据
            if (snapshot.hasData) {
                return Text("${snapshot.data}", style: TextStyle(fontSize: 72));
            }
            //等待
            return CircularProgressIndicator();
        },
    ),
),

Stream与StreamBuilder组件

定义stream

final future = Future.delayed(Duration(seconds: 1), () => 42);
//定义一个stream
final stream = Stream.periodic(Duration(seconds: 1), (_) => 42);

@override
void initState() {
    future.then((value) => print("future conmpleted:$value"));
    //监听一个stream
    stream.listen((event) {
        print("stream:$event");
    });
    super.initState();
}

StreamBuilder监听

//定义一个StreamController
final controller = StreamController();

//运行结束后关闭stream
@override
void dispose() {
    //关闭stream的controller
    controller.close();
    super.dispose();
}

//
Center(
    child: DefaultTextStyle(
        //DefaultTextStyle子级统一样式
        style: Theme.of(context).textTheme.headline4,
        child: Column(
            children: [
                //往stream里添加事件
                RaisedButton(
                    child: Text('10'), onPressed: () => controller.sink.add(10)),
                RaisedButton(
                    child: Text('1'), onPressed: () => controller.sink.add(1)),
                RaisedButton(
                    child: Text('Hi'),
                    onPressed: () => controller.sink.add('hi')),
                
                //往stream里添加错误
                RaisedButton(
                    child: Text('Error'),
                    onPressed: () => controller.sink.addError('oops')),
                
                //关闭stream
                RaisedButton(
                    child: Text('DONE'), onPressed: () => controller.sink.close()),
                
                //定义一个StreamBuilder开始监听stream
                StreamBuilder(
                    stream: controller.stream,
                    builder: (context, snapshot) {
                        switch (snapshot.connectionState) {
                                //none 代表stream或builder为空
                            case ConnectionState.none:
                                return Text('NONE:没有数据流');
                                break;
                            case ConnectionState.waiting:
                                return Text('WAITTING:等待数据流');
                                break;
                                //连接状态时active的话,代表有数据或者有错误
                            case ConnectionState.active:
                                if (snapshot.hasError) {
                                    return Text('ACTIVE:错误:${snapshot.error}');
                                } else {
                                    return Text('ACTIVE:正常:${snapshot.data}');
                                }
                                break;
                            case ConnectionState.done:
                                return Text('DONE:数据流已经关闭');
                                break;
                        }
                        return Container();
                    },
                ),
            ],
        ),
    ),
),

StreamController.broadcast

//开启广播,允许被很多人监听,开启广播后,数据不会帮你缓存
final controller = StreamController.broadcast();

//第一种监听方式
@override
void initState() {
    super.initState();
    controller.stream.listen((event) {
        print("event:$event");
    },
                             //错误
                             onError: (err) => print("ERROR:$err"),
                             //关闭
                             onDone: () => print('DONE'));
}

//第二种监听方式
//StreamBuilder

async*

//新建一个Stream方法,持续返回一个时间
Stream<DateTime> getTime() async* {
    while (true) {
        await Future.delayed(Duration(seconds: 1));
        yield DateTime.now();
    }
}

//-------------------------------------------------------
//第一种监听方式
getTime().listen((event) {
    print('event:$event');
}, onDone: () => print('DONE'));

//第二种监听方式
 StreamBuilder(
                stream: getTime(),
                builder: (context, snapshot) {
                    ...
                        ....

实例:

import 'dart:async';
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _inputController = StreamController.broadcast();
  final _scoreController = StreamController.broadcast();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: StreamBuilder(
            stream: _scoreController.stream.transform(TallyTransformer()),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text("Score:${snapshot.data}");
              }
              return Text('Score:0');
            }),
      ),
      body: Stack(
        children: [
          ...List.generate(
              5, (index) => Puzzle(_inputController.stream, _scoreController)),
          Align(
              alignment: Alignment.bottomCenter,
              child: KeyPad(_inputController, _scoreController)),
        ],
      ),
    );
  }
}

class KeyPad extends StatelessWidget {
  final _inputController;
  final _scoreController;
  KeyPad(this._inputController, this._scoreController);
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      childAspectRatio: 3 / 1, //改变大小
      crossAxisCount: 3,
      shrinkWrap: true, //真空包装,把组件压缩成组件自己的大小
      physics: NeverScrollableScrollPhysics(), //不要滚动
      padding: EdgeInsets.all(0.0), //IOS下边有padding
      children: List.generate(9, (index) {
        return FlatButton(
            shape: RoundedRectangleBorder(),
            color: Colors.primaries[index][200], //primaries
            onPressed: () {
              _inputController.add(index + 1);
              _scoreController.add(-2);
            },
            child: Text(
              '${index + 1}',
              style: TextStyle(fontSize: 24),
            ));
      }),
    );
  }
}

class TallyTransformer implements StreamTransformer {
  int sum = 0;
  StreamController _controller = StreamController();

  @override
  Stream bind(Stream stream) {
    stream.listen((event) {
      sum += event;
      _controller.add(sum);
    });
    return _controller.stream;
  }

  @override
  StreamTransformer<RS, RT> cast<RS, RT>() => StreamTransformer.castFrom(this);
}

class Puzzle extends StatefulWidget {
  final inputStream;
  final scoreStream;
  Puzzle(this.inputStream, this.scoreStream);

  @override
  _PuzzleState createState() => _PuzzleState();
}

class _PuzzleState extends State<Puzzle> with SingleTickerProviderStateMixin {
  int a, b, c;
  Color color;
  double x;
  AnimationController _controller;

  reset([from = 0.0]) {
    c = Random().nextInt(9) + 1;
    b = Random().nextInt(8);
    a = c - b;
    x = Random().nextDouble() * 300;
    color = Colors.primaries[Random().nextInt(Colors.primaries.length)][200];
    _controller.duration =
        Duration(milliseconds: Random().nextInt(5000) + 5000);
    _controller.forward(from: from);
  }

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(vsync: this);
    reset(Random().nextDouble());

    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        reset();
        widget.scoreStream.add(-3);
      }
    });

    widget.inputStream.listen((input) {
      if (input == a + b) {
        reset();
        widget.scoreStream.add(5);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Positioned(
          left: x,
          top: 600 * _controller.value - 100,
          child: Container(
            decoration: BoxDecoration(
                color: color.withOpacity(0.5),
                border: Border.all(color: Colors.black),
                borderRadius: BorderRadius.circular(24)),
            padding: EdgeInsets.all(8.0),
            child: Text('$a+$b', style: TextStyle(fontSize: 24)),
          ),
        );
      },
    );
  }
}

posted @ 2021-02-18 19:26  漫游者杰特  阅读(179)  评论(0编辑  收藏  举报