「这是我参加11月更文应战的第25天,活动概况检查:2021最后一次更文应战」
在之前的文章中,咱们已经学习了Future
异步编程和Isolate
多线程的运用,今日咱们来看一下,怎么运用异步编程与多线程结合运用;
异步与多线程结合运用
咱们先来看一段代码:
void main() {
testIsoLoad();
}
void testIsoLoad() {
Future(() => compute(func, 123)).then((value) => print('1'));
Future(() => compute(func, 123)).then((value) => print('2'));
Future(() => compute(func, 123)).then((value) => print('3'));
Future(() => compute(func, 123)).then((value) => print('4'));
Future(() => compute(func, 123)).then((value) => print('5'));
}
func(int message) {}
运转工程,检查打印成果:
从打印成果咱们能够得到定论,这几个print
操作时异步的,他是在子线程处理的;
可是依照咱们之前对Future
的研讨,多个Future
之间应该是同步的才对,那么为什么此处却变成了异步的呢?接下来,咱们在其他代码坚持不变的状况下,将testIsoLoad
办法中的代码进行如下修正:
然后,咱们运转工程,看到一下打印成果:
正告咱们屡次运转项目,最后发现打印顺序都是1、2、3、4、5
,那么这是为什么呢?怎样又变成了同步的呢?咱们仅仅只是将=>
的调用方式换成了{}
,怎样代码的履行成果就不一样了呢?
需要注意的是,=>
在调用的过程中,有将履行成果进行return
操作的含义,也便是说=> compute(func, 123)
的履行,会将compute(func, 123)
的成果进行return
操作,咱们来验证一下,将testIsoLoad
办法修正如下:
运转成果如下:
屡次运转之后,发现成果并不是固定的,也便是说,咱们进行了return
操作之后,同步的履行流程变成了异步的,这也验证了咱们上边所说的=>
函数的调用方式会将成果进行return
操作;
假如在Future
中return
了子线程的Future
(compute
是对Future
的封装),那么其then
将会处理子线程的异步使命;那么已然then
是子线程的异步操作了,那么Future
中的使命是什么状况呢?
咱们在Future
中增加如下打印:
运转成果;
能够看到,尽管then
处理的是子线程的异步使命,可是Future
中仍然还是同步使命;
Future与微使命
咱们来看下边这样代码:
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
很明显,咱们都能才到履行成果是:异步使命先履行,然后履行微使命;
假如,咱们持续给f
增加一个then
办法呢?
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
f.then((value) {
print('微使命2');
});
此时的履行成果怎么呢?
成果是微使命2
比微使命1
先履行,这是由于then
办法咱们能够看做和Future
的使命是一个整体,也便是then
办法(一个微使命)先增加进入队列,然后微使命1
的微使命会增加到then
办法后边,所以then
办法先履行;
不仅仅如此,咱们再增加一个whenComplete
办法检查打印成果:
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
f.whenComplete(() {
print('完成');
});
f.then((value) {
print('微使命2');
});
打印成果如下:
whenComplete
也能够看做和Future
的使命是一个整体,whenComplete
和then
会依照增加顺序履行;
异步与多线程的选择
那么究竟什么时分运用异步使命,什么时分运用多线程操作呢?
尽管Future
是个异步使命,可是在Future
中的耗时操作是会堵塞主线程的。看如下代码:
咱们在相机按钮的点击办法中增加了一个for
循环来模拟耗时操作,能够从打印成果看到,当Future
中的耗时操作开端履行之后,界面被堵塞,无法滑动!当耗时操作结束之后,才能进行滑动操作;
这个时分,咱们能够运用compute
来操作:
将耗时操作放在compute
的办法中,将不会堵塞主线程,此处能够直接运用compute
,不必Future
;