愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

Dart学习笔记(八):异步支持与async/await

Dart中有类似于Javascriptasync/await语法,用以支持异步场景。在Dart里,很多库方法会返回Future或者Stream对象,这些方法是异步的。对于这些方法,它们会在调用完后就返回了,这种情况下,如何获得调用结果呢?方法有两种:

  • 使用async/await
  • 使用Future API

同样地,从Stream中获取数据的方式也有两种:

  • 使用async和异步forawait for
  • 使用Stream API

我们都知道,使用async/await的好处,便是可以使得异步代码写起来像同步代码,如:await lookUpVersion()

一、async关键字

asyncawait是配套使用的,即使用await时,其方法必须带有async关键字,如:

checkVersion() async {
    var version = await lookUpVersion();
    if (version == expectedVersion) {
        // ...
    } else {
        // ...
    }
}

因此,使用async关键字可以声明一个异步方法,即:

checkVersion() async {
    // ...
}

lookUpVersion() async => /* ... */

async方法返回值类型为Future,如:

Future<String> lookUpVersion() async => '1.0.0'

二、await

await的语法如下:

await expression

一个异步方法内部可以多次地使用await表达式,如:

buyItem(int id) async {
    var remainedCount = await getItemRemainedNumber(id);
    var stockUpdatedRes = await updateStock(id);
    return stockUpdatedRes;
}

对于await expression而言,expression应该是一个Future对象,如果expression不是一个Future对象,则Dart会自动地将它转为Future对象

三、异常处理

处理await异常,可以使用try...catch...finally语句块,如:

try {
    var server = await HttpServer.bind(InternectAddress.LOOPBACK_IP_V4, 4044);
} catch (e) {
    // ...
}

四、在循环中使用异步

异步for循环的语法形式如下:

await for (variable declaration in expression) {
    // ...
}

其中,expression的类型必须是Stream类型,并且执行流程为:

  1. 等待直到stream返回一个数据
  2. 使用stream返回的参数执行for循环代码
  3. 重复执行步骤1和步骤2,直到stream数据返回完毕
  4. 如果遇到break或者return语句,可以提前停止接收stream的数据

注意: 异步for也需要在async方法里执行,如果要在main()方法里执行,则main()方法要标记为async

例子:

main() async {
    // ...
    await for (var request in requestServer) {
        handleRequest(request);
    }
    // ...
}