使用rootBundle

时间:2018-07-14 15:57:33

标签: dart flutter

我需要从文件中加载字符串。以下代码始终返回null:

static String  l( String name ) {

    String contents;

    rootBundle
     .loadString( 'i10n/de.yaml' )
     .then( (String r)  { contents = 'found'; print( 'then()' ); })
     .catchError( (e) { contents =  '@Error@'; print( 'catchError()' );  })
     .whenComplete(() { contents = 'dd'; print( 'whenComplete()' );  })
     ;

    print( 'after' );

    if ( null == contents ) {
      return '@null@';
    }

    String doc = loadYaml( contents );

    return doc;

  }

我已将其添加到pupspec.yaml部分的flutter:部分:

  assets:
    - i10n/de.yaml
    - i10n/en.yaml

文件i10n / de.yaml存在。

我知道rootBundle.loadString()是异步的。因此,我追加了then()调用-假设

(String r)  { contents = 'found'; }

仅在rootBundle.loadString()返回的Future能够返回值时执行。

实际上,该方法始终返回“ @ null @”。因此,我添加了print()语句,其输出如下:

I/flutter (22382): after
I/flutter (22382): then()
I/flutter (22382): whenComplete()

好吧,显然loadString()的未来执行要比最终的print()语句晚。

问:但是我如何强制执行未来,以便我可以获取其价值?

换句话说:如何在某些代码中包装一些异步内容以立即获取其值?

PS:颤抖/飞镖的第一天。可能是一个琐碎的问题...

1 个答案:

答案 0 :(得分:0)

.then()正在执行,但是之后其余部分。正如您提到的,loadString()返回一个Future,因此在将来完成。要等待Future完成,请使用await。 (请注意,当您将函数标记为异步时,该函数现在必须返回Future本身-因为它必须等待loadString在将来完成,因此它本身必须在将来完成...)当您调用{ {1}}您将不得不等待结果。

l('something')

由于必须等待(很多等待-文件读取,http请求完成等),许多实用程序功能变成Future<String> l(String name) async { try { String contents = await rootBundle.loadString('i10n/de.yaml'); return contents == null ? '@null@' : loadYaml(contents); } catch (e) { return 'oops $e'; } } 没什么大不了的。最终,您将获得类似(从async进行调用)之类的东西

initState

在i18nStuff就绪时设置窗口小部件的状态,并在其内部构建窗口小部件以在虚拟ui几毫秒之间切换直到准备就绪,然后再切换真实UI。

refresh(String s) {
  l(s).then((r) {
    setState(() {
      i18nStuff = r;
    });
  });
}