zoukankan      html  css  js  c++  java
  • dart类初始化 future方案

    question:

    Let's assume that an initialization of MyComponent in Dart requires sending an HttpRequest to the server. Is it possible to construct an object synchronously and defer a 'real' initialization till the response come back?

    In the example below, the _init() function is not called until "done" is printed. Is it possible to fix this?

    import 'dart:async';
    import 'dart:io';
    
    class MyComponent{
      MyComponent() {
        _init();
      }
    
      Future _init() async {
        print("init");
      }
    }
    
    void main() {
      var c = new MyComponent();
      sleep(const Duration(seconds: 1));
      print("done");
    }
    

    Output:

    done
    init


    solution1 ,

    A constructor can only return an instance of the class it is a constructor of (MyComponent). Your requirement would require a constructor to return Future<MyComponent> which is not supported.

    You either need to make an explicit initialization method that needs to be called by the user of your class like:

    class MyComponent{
      MyComponent();
    
      Future init() async {
        print("init");
      }
    }
    
    void main() async {
      var c = new MyComponent();
      await c.init();
      print("done");
    }
    

      

    or you start initialization in the consturctor and allow the user of the component to wait for initialization to be done.

    class MyComponent{
      Future _doneFuture;
    
      MyComponent() {
        _doneFuture = _init();
      }
    
      Future _init() async {
        print("init");
      }
    
      Future get initializationDone => _doneFuture
    }
    
    void main() async {
      var c = new MyComponent();
      await c.initializationDone;
      print("done");
    }
    

      

    When _doneFuture was already completed await c.initializationDone returns immediately otherwise it waits for the future to complete first.

    solution2 

    Probably the best way to handle this is with a factory function, which calls a private constructor.

    In Dart, private methods start with an underscore, and "additional" constructors require a name in the form ClassName.constructorName, since Dart doesn't support function overloading. This means that private constructors require a name, which starts with an underscore (MyComponent._create in the below example).

    import 'dart:async';
    import 'dart:io';
    
    class MyComponent{
      /// Private constructor
      MyComponent._create() {
        print("_create() (private constructor)");
    
        // Do most of your initialization here, that's what a constructor is for
        //...
      }
    
      /// Public factory
      static Future<MyComponent> create() async {
        print("create() (public factory)");
    
        // Call the private constructor
        var component = MyComponent._create();
    
        // Do initialization that requires async
        //await component._complexAsyncInit();
    
        // Return the fully initialized object
        return component;
      }
    }
    
    void main() async {
      var c = await MyComponent.create();
    
      print("done");
    }
    

      

    This way, it's impossible to accidentally create an improperly initialized object out of the class. The only available constructor is private, so the only way to create an object is with the factory, which performs proper initialization.

  • 相关阅读:
    node 安装及环境配置
    vue 多级嵌套组件的通信方式
    uniapp 直播(推流)
    css3 弹出层居中(防止穿透滚动)
    uniapp App打开没有关掉后台,去查看其它东西一段时候回来后,页面会变空白
    uniapp 根据给定的经纬度、地址address,调取地图导航
    208道面试题,答案
    十分钟了解单元测试
    异常处理的一些见解
    MySQL(MariaDB)常用DOM命令
  • 原文地址:https://www.cnblogs.com/pythonClub/p/15780777.html
Copyright © 2011-2022 走看看