Asynchronous async对呼叫者来说是滚雪球,can';不能使构造函数异步

Asynchronous async对呼叫者来说是滚雪球,can';不能使构造函数异步,asynchronous,async-await,dart,flutter,Asynchronous,Async Await,Dart,Flutter,我有一个函数loadData,可以从文件中加载一些文本: Future<String> loadAsset() async { return await rootBundle.loadString('assets/data/entities.json'); } parseData方法不是异步的,它接收一个字符串,对其进行解析,并返回一个对象列表: List<Entity> parseData(String jsonString) { ... } List pa

我有一个函数
loadData
,可以从文件中加载一些文本:

Future<String> loadAsset() async {
  return await rootBundle.loadString('assets/data/entities.json');
}
parseData
方法不是异步的,它接收一个
字符串
,对其进行解析,并返回一个对象列表:

List<Entity> parseData(String jsonString) {
  ...
}
List parseData(字符串jsonString){
...
}
但是由于
loadEntities
必须标记为
async
,这就要求它返回
Future
,但实际上,它不是
Future
,因为我使用
wait
,它会等待
loadAsset
方法完成,然后使用结果调用
parseData
函数

这很容易变成
async
调用的雪球,因为使用
loadEntities
的每个方法也必须标记为
async

另外,我不能在类构造函数中使用
loadEntities
,因为构造函数应该标记为
async
,这在Dart中是不允许的


我在Dart中使用的
async/await
模式是否错误?如何在类构造函数中使用
loadEntities
方法?

否,异步会传染,无法从异步返回到同步执行

async
/
await
是返回未来()的方法的唯一语法糖。然后(…)


将方法标记为
async
只允许在其主体内使用
wait
。如果没有
async
,您仍然需要返回
Future
,以便调用代码仅在
loadAsset()
的结果可用后执行。

您可以直接使用从异步调用返回的Future。这看起来像这样:

class HasAsync {
  HasAsync() {
    asyncFunction().then((val) {
      print(val);
    });
  }

  Future<int> asyncFunction() async {
     int val = await otherFunction();
     return val;
  }
}
类HasAsync{ hasancync(){ asyncFunction()。然后((val){ 打印(val); }); } Future asyncFunction()异步{ int val=等待其他函数(); 返回val; } } 在非异步函数中不能使用wait

由于您已将其标记为“颤振”,我猜这是在颤振应用程序中。如果是这种情况,请查看-它可能有助于您尝试执行的操作。

只是一个更正: 异步方法不会传染。 测试构造函数调用异步方法sayHello。 这演示了当不允许将ctor声明为异步时,如何让ctor进行异步调用。 main方法被标记为async,这样应用程序就不会在sayHello完成之前关闭。这不是内在的要求

class Test
{
  Test()
  {
    sayHello();
  }

  void sayHello() async
  {
    await Future.delayed(Duration(seconds: 4) , () => print("Hello"));

    print("We said hello");
  }

}

  void main() async
  {

    doTest();

  // wait for hello to be output
    await Future.delayed(Duration(seconds: 6) , ()  {});

    print("Ending");
  }

  void doTest()
  {
        Test();
  }

我知道我可能太晚了,你无法利用这个答案,但我还是希望有人会觉得它有用。这是我的两分钱

当我第一次尝试弄清楚什么是异步编程以及如何使用异步编程时,我的思维过程与您相同

因为问题是关于颤振的,所以我将使用dart来解释这一点

首先,让我们深入了解在异步编程中使用异步等待的基本目的

根据颤振文档,async和Wait关键字的目的是声明性地将函数标记为asynchronous并使用其结果

  • 要定义异步函数,请在函数体之前添加async
  • wait关键字仅在异步函数中有效
因此,每当您试图从标记为异步的函数获取输出时,它将别无选择,只能返回未来。请看以下示例以了解更多说明

  • 首先,你有一个函数可以做一些计算
  • 其次,您有一个简单的函数,它通过执行一个简单的HTTPGET请求从API获取数据
  • 最后是另一个函数,它将处理一些数据并打印一些值

    void processInfo(){
      calculateStuff();
      Future<Map> decodedData = getDataFromInternet();
      getDataProcessed(decodedData);
    }
    
    3。方法三-以同步功能(非传染性方式)使用异步方法的结果。

    在这种情况下,processInfo()函数将稍有更改,即getDataProcessed()将不再在此方法中调用,并且看起来类似于此

    void getDataProcessed(Map data) {
     //this will simply print the data object which is complete result which is by 
     //no way is a promise object
     print(data);
    }
    
        void processInfo(){
          calculateStuff();
          getDataFromInternet();
        }
    
    我们可以使用getDataFromInternet()函数的结果来调用getDataProcessed()函数,而不是在processInfo()函数中调用getDataProcessed()。这意味着我们不必将processInfo()标记为异步,我们可以在执行完getDataFromInternet()方法后处理getDataProcessed()方法。下面的代码示例演示如何执行此操作

    void getDataFromInternet() async {
     http.Response response = await http.get(this._apiPath);
    
     Map decodedData;
    
     if (response.statusCode != 200)
       print("invalid response. cannot proceed!");
     else {
       decodedData = jsonDecode(response.body);
     }
    
     //in this case, since we are awaiting for get results response and the 
     //function is not expected to return anything the data type passed into      
     //getDataProcessed() function now will be of type Map rather than being type      
     //Future<Map> . Thus allowing it to be a synchronous function and without 
     //having to handle the future objects.
     getDataProcessed(decodedData);
    }
    
    
    void getDataProcessed(Map data) {
     //this will simply print the data object which is complete result which is by 
     //no way is a promise object
     print(data);
    }
    
    void getDataFromInternet()异步{
    http.Response-Response=wait http.get(this.\u apiPath);
    地图解码数据;
    如果(response.statusCode!=200)
    打印(“无效响应。无法继续!”);
    否则{
    decodedData=jsonDecode(response.body);
    }
    //在本例中,由于我们正在等待get results响应和
    //函数不应返回传入的任何数据类型
    //getDataProcessed()函数现在将是Map类型,而不是
    //因此,允许它是一个同步函数,并且没有
    //必须处理未来的对象。
    getDataProcessed(解码数据);
    }
    void getDataProcessed(地图数据){
    //这将简单地打印数据对象,它是由
    //不可能是承诺的对象
    打印(数据);
    }
    
    所以重新修改这个长答案

    • async/await只是标记异步函数的声明方式
    • 当调用异步函数时,可以通过3种方式处理它。
    • 获取返回的未来,并使用“then()”函数像承诺一样处理它,因此无需标记父项 函数异步
    • 将父函数标记为async,并使用wait处理返回的对象,以强制函数等待结果
    • 在异步函数末尾使用异步函数的输出调用所需函数。这将允许主 函数在等待时继续非依赖函数
          void processInfo() async{
            calculateStuff();
            //now you can simply await that result and process the result rather
            //than handling a Future<Map> result in this case.
            //Note: it is not required to use future variable because we are awaiting 
            //for result
            Map decodedData = await getDataFromInternet();
            getDataProcessed(decodedData);
          }
      
      void getDataProcessed(Map data) {
       //this will simply print the data object which is complete result which is by 
       //no way is a promise object
       print(data);
      }
      
          void processInfo(){
            calculateStuff();
            getDataFromInternet();
          }
      
      void getDataFromInternet() async {
       http.Response response = await http.get(this._apiPath);
      
       Map decodedData;
      
       if (response.statusCode != 200)
         print("invalid response. cannot proceed!");
       else {
         decodedData = jsonDecode(response.body);
       }
      
       //in this case, since we are awaiting for get results response and the 
       //function is not expected to return anything the data type passed into      
       //getDataProcessed() function now will be of type Map rather than being type      
       //Future<Map> . Thus allowing it to be a synchronous function and without 
       //having to handle the future objects.
       getDataProcessed(decodedData);
      }
      
      
      void getDataProcessed(Map data) {
       //this will simply print the data object which is complete result which is by 
       //no way is a promise object
       print(data);
      }
      
      void main() {
        final myFuture = Future(() {
          print('Creating the future.'); // Prints second.
          return 12;
        });
        print('Done with main().'); // Prints first.
      }
      
      void main() {
        Future.delayed(
          const Duration(seconds: 3),
          () => 100,
        ).then((value) {
          print('The value is $value.'); // Prints later, after 3 seconds.
        });
        print('Waiting for a value...'); // Prints first.
      }