我知道我可能为时已晚,无法使用此答案,但无论如何我都在写它,希望有人会发现它有用。所以这是我的两分钱。
当我第一次尝试弄清楚什么是异步编程以及如何使用它时,我的思考过程和你一样。
由于问题是关于 Flutter 的,我就用 dart 来解释一下。
首先,让我们深入了解在异步编程中使用 async await 的基本目的。
根据 Flutter 文档,async 和 await 关键字的目的是声明性地将函数标记为异步并使用它的结果。
- 要定义异步函数,请在函数体之前添加异步
- await 关键字仅适用于异步函数。
因此,每当您尝试从标记为异步的函数中获取输出时,它将别无选择,只能返回一个 Future。请查看以下示例以获得更多说明。
所以在同步编程中,这意味着所有三个函数将一个接一个地执行。但是假设第二个函数 getDataFromInternet() 是异步调用的。一个简单的实现如下所示。
Future<Map> 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);
}
return decodedData;
}
所以上面的函数需要返回一个future。问题是为什么?
这很简单。在这种情况下,这是因为我们想要返回一些东西,并且在执行 return 语句时,来自“获取请求”的数据可能或可能在那个时候不可用。
因此,该函数返回一个 Future 类型的结果,该结果要么处于完整状态,要么处于不完整状态。
那么我们如何处理这个结果呢?事实上,这可以通过 3 种方式完成。
1.方法一 - 把它当作一个承诺来处理
因此,一旦 getDataFromInternet() 函数在此示例中返回 Future 结果,您就需要该 Future 结果的过程,就像您在 javascript 中处理 promise 的方式一样。请参考下面的代码示例。
void getDataProcessed(Future<Map> data) {
print('getting data from future map');
data.then((d) {
print(d);
});
}
2。方法二——将父函数标记为异步(传染方式)
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);
}
所以在这种情况下,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);
}
3.方法三 - 在同步函数中使用异步方法的结果(非传染方式)
在这种情况下,processInfo() 函数将略有变化,即 getDataProcessed() 将不再在此方法中调用,并且看起来像这样。
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);
}
所以修改这个长答案,
- async/await 只是标记异步函数的声明方式
- 当调用异步函数时,可以通过 3 种方式对其进行处理。
- 使用'then()'函数获取返回Future并像promise一样处理它,因此无需标记父级
函数异步
- 将父函数标记为async,并用await处理返回的对象,强制函数等待结果。
- 在异步函数结束时使用异步函数的输出调用所需的函数。这将允许主要
函数在等待时继续非依赖函数
async 函数的结果和一个 async 函数的结果得到
结果它可以在最后进入另一个函数并执行它
接收到的数据。