异步操作(Future)

河图脚本有可能获得一个 Dart 中的 Future 对象。为了方便起见,我们提供了一个简单的封装,让脚本可以和 Future 交互。

你可以在脚本中通过 then() 来传递一个脚本中的函数,它将会在这个 Future 完成后被执行:

import 'package:hetu_script/hetu_script.dart';

Future<void> fetch() {
  // Imagine that this function is fetching user info from another service or database.
  return Future.delayed(
      const Duration(seconds: 2), () => print('Hello world after 2 seconds!'));
}

void main() {
  final hetu = Hetu();
  hetu.init(externalFunctions: {'fetch': fetch});
  hetu.eval(r'''
      external fun fetch
      final future = fetch()
      future.then((value) {
        print('future completed!')
      })
  ''');
}

手动创建一个 Future 对象

河图 0.4.0 版本之后,可以通过 Future 类的构造函数手动创建一个 Future 对象:

final a = Future( () => 42 )
a.then( (value) => print(value) )
print(41)

上面的代码将会先打印 41,然后打印 42。

你也可以在函数定义代码块的括号之前添加 async 关键字来方便的返回一个 Future 对象:

// 函数声明时附带async
fun testAsync async {
  // some code
}

// 匿名函数附带async
() async {
  // some code
} ().then((value) {
  // 匿名函数的好处是可以原地立即执行,这种用法类似 Javascript
})

这种方式声明的函数,本质上还是创建了一个 Dart 的 Future 对象。然后将脚本函数作为其参数。

等待多个 Future 返回

河图 0.4.0 版本之后,可以使用 Future 类上的静态函数 wait() 来等待多个 Future 完成,然后统一返回。

注意在脚本中,不能使用 Dart 的泛型参数,因此所有的 Future 返回的都是 dynamic 类型。

async asyncFunc1 => 41
async asyncFunc2 => 42

Future.wait([asyncFunc1(), asyncFunc2()]).then((valueList) {
  print(valueList)
})

上述的代码将会打印:

[
  41,
  42
]

await

在河图 0.5.0 版本之后,可以在部分情况下支持 await 关键字,来避免过于复杂的 then 形式的回调函数。

目前这是一个试验性质的功能,可能会有一些潜在的 bug,而且也并非在所有场景下都支持使用 await

目前仅可以在普通的表达式中使用。包括变量初始化表达式等等。

但不能在 for 循环的初始化表达式,以及函数调用参数中的表达式中使用 await

可以使用 await 的场合的简单例子:

final result = await fetch() * await valueFuture() * await sumAll();
Last Updated:
Contributors: 邵燃, chengfubeiming, hythloday@live.com