Futuro de programación asincrónica de Flutter y Dart, Inicio rápido de transmisión


Dart es un modelo de subproceso único y el código que escribimos se ejecuta en el mismo subproceso. Si realiza una operación que requiere mucho tiempo, bloqueará la aplicación. Use Future y Stream para escribir tareas asincrónicas en Dart.

Futuro

Future es un proceso de cálculo que no se completará de inmediato. En pocas palabras, es un proceso de ejecución asíncrono, que debe usarse junto con async y await. El código después de esto no se bloqueará, esperando a que se complete el cálculo antes de devolver el resultado.

PromiseSimilar a y async, en JavaScript await.

uso

void main()  {
  requestApi();
  doSomething1();
  doSomething2();
}

doSomething1() {
  print("doSomething1");
}

doSomething2() {
  print("doSomething2");
}

/// 异步请求数据
Future requestApi() async {
  ....
  return 
}

Dado que requestApi()es una función asíncrona, después de que se ejecute el programa, no esperará a que se complete la ejecución de la función, y el siguiente código también comenzará a ejecutarse inmediatamente.

espera el resultado

Si desea realizar otras operaciones después de que la función asincrónica devuelva el resultado, puede usar el then()método para escuchar.

void main()  {
  requestApi().then((value) {
    /// 结果返回,开始处理
    showApiData(value);
  });
  print("程序开始运行...");
}

............
  
showApiData(dynamic value){
  print("展示获取的数据: $value");
}

FuturoConstructor

const FutureBuilder({
    Key? key,
    this.future,
    this.initialData,
    required this.builder,
})

FutureBuilder construirá un Widget basado en el resultado de retorno del futuro entrante.

Ejemplo de uso

Generalmente se usa para actualizar la interfaz de usuario después de una solicitud de red.
inserte la descripción de la imagen aquí

class FutureBuilderDemo extends StatefulWidget {
  const FutureBuilderDemo({Key key}) : super(key: key);

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

class _FutureBuilderDemoState extends State<FutureBuilderDemo> {
  Future<String> futureData;

  @override
  void initState() {
    super.initState();
    /// ui初始化时开始网络请求数据
    futureData = getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FutureBuilder 测试'),
      ),
      body: Container(
        child: Center(
          child: FutureBuilder<String>(
              future: futureData,
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.hasData) {
                  return Text("获取的数据==${snapshot.data}");
                } else if (snapshot.hasError) {
                  return Icon(Icons.error_outline);
                } else {
                  return CircularProgressIndicator();
                }
              }),
        ),
      ),
    );
  }

  Future<String> getData() async {
    /// 模拟网络请求,等待5秒返回结果
    await Future.delayed(Duration(seconds: 5));

    /// 返回一个错误
    // return Future.error("error");
    /// 返回一个成功的结果
    return "Hello,world";
  }
}

Arroyo

Stream es una secuencia de eventos asíncronos, equivalente a un iterable asíncrono. A diferencia de Future, que es solo un proceso de ejecución de eventos, Stream puede enviar y ejecutar múltiples eventos. Los escenarios de uso son diferentes.

uso

Hay dos formas de crear, una es una transmisión de suscripción única y la otra es una transmisión a la que se puede suscribir varias veces, es decir, se puede transmitir.

Después de suscribirse (escuchar), se devolverá un StreamSubscription, que es un observador.

Ambos constructores tienen un parámetro opcional sync, cuyo valor predeterminado es falso.

..........
   bool sync = false}) {
return sync
        ? _SyncStreamController<T>(....)
        : _AsyncStreamController<T>(...);

Se puede ver en el código fuente que se crea syncun StreamController de evento asíncrono syncpara falso y un StreamController síncrono para verdadero. Debido a que Stream se usa en la mayoría de los escenarios para la asincronía, simplemente no podemos pasarlo.

suscripción única

/// 直接使用构造函数
StreamController<String> _controller = StreamController();
StreamSubscription subscription = _controller.stream.listen((event) {
    print("subscription 接收到 $event");
});

suscripción de transmisión

void main() {
  /// 使用工厂方法构造可广播的Controller
  StreamController _controller = StreamController.broadcast();

  /// 使用多个观察者订阅同一个Stream.
  StreamSubscription subscription1 =
      _controller.stream.listen((event) => print("sub1 接收到 $event"));
  StreamSubscription subscription2 =
      _controller.stream.listen((event) => print("sub2 接收到 $event"));
  StreamSubscription subscription3 =
      _controller.stream.listen((event) => print("sub3 接收到 $event"));

  /// 发送事件后,所有已订阅的观察者的都能接收到事件。
  _controller.add("Hello");
}

Después de ejecutarlo varias veces, los resultados de la impresión son los siguientes:

sub1 接收到 Hello
sub2 接收到 Hello
sub3 接收到 Hello

Process finished with exit code 0

En conclusión:

Cuanto antes se suscriba un evento ( listen), mayor será la prioridad del evento recibido.

liberar recursos

Después de usar el evento o cuando el Widget esté cerrado en Flutter, recuerda cerrar el Stream al mismo tiempo.

_controller.stream.listen((event) {}, onDone: () => print("收到onDone事件"));

_controller.close();
subscription.cancel();

El método de devolución de llamada onDone se activa automáticamente después del cierre.

StreamBuilder

En la interfaz, StreamBuilder generalmente se usa para cooperar con Stream. Se puede implementar una interfaz multiestado.

Ejemplo de uso

inserte la descripción de la imagen aquí

/// 定义3种ui状态
enum UIState { type_1, type_2, type_3 }

class StreamBuilderDemo extends StatefulWidget {
  const StreamBuilderDemo({Key key}) : super(key: key);

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

class _StreamBuilderDemoState extends State<StreamBuilderDemo> {
  StreamController<UIState> _controller;

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

    /// 初始化controller
    _controller = StreamController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('StreamBuilder测试'),
      ),
      body: Container(
        // height: double.infinity,
        child: Center(
          child: StreamBuilder<UIState>(

              /// 传入stream
              stream: _controller.stream,
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.hasData) {
                  /// hasData代表有接收到事件
                  var data = snapshot.data;
                  Widget widget;

                  ///根据返回不回的类型,展示不同的图片
                  switch (data) {
                    case UIState.type_1:
                      widget = Icon(Icons.timer, size: 100);
                      break;
                    case UIState.type_2:
                      widget = Icon(Icons.done, size: 100);
                      break;
                    case UIState.type_3:
                      widget = Icon(Icons.ac_unit, size: 100);
                      break;
                  }
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      widget,
                      Text("$data"),
                    ],
                  );
                } else if (snapshot.hasError) {
                  /// 接收到错误事件
                  return Icon(Icons.error_outline_rounded, size: 100);
                } else {
                  /// 什么都没有,代表没还有接收到事件
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      CircularProgressIndicator(),
                      Text("初始化中,还没接收到收到状态"),
                    ],
                  );
                }
              }),
        ),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: () => generateState(), child: Icon(Icons.add)),
    );
  }

  /// 随机生成不同的状态,发送事件
  generateState() {
    var randomIndex = Random().nextInt(UIState.values.length);
    _controller.add(UIState.values[randomIndex]);
  }

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

    /// 回收资源
    _controller.close();
  }
}

Supongo que te gusta

Origin blog.csdn.net/adojayfan/article/details/120697047
Recomendado
Clasificación