아니에요. Java에서 오면 그렇게 연결하기 쉬워요. Dart의 Future는 나중에 도착하는 값이지 스레드가 아니에요. 앱 전체가 isolate 하나에서 돌고, 그 isolate에는 이벤트 루프 하나를 돌리는 스레드가 하나 있어요. 게다가 async 함수는 첫 await까지 동기로 실행돼요. filterRows 안에는 await가 없으니까 루프 전체가 탭 핸들러 그 자리에서, Future가 반환되기도 전에 끝까지 돌아요. 스피너를 그릴 프레임은 그 뒤에서 이벤트 큐에 앉아 기다리고요. await 뒤의 리빌드는 느린 부분이 아니에요. 루프가 끝날 때까지 시작조차 못 하거든요.
그 루프에서 일을 빼려면 isolate가 하나 더 있어야 해요.
import 'dart:isolate';
List<Entry> filterRows(List<Entry> rows, String query) =>
rows.where((r) => r.matches(query)).toList();
// in the tap handler
final result = await Isolate.run(() => filterRows(rows, query));
이제 await는 다른 isolate가 보내는 메시지를 기다리고, 그동안 이벤트 루프는 비어 있어요. 키워드가 일을 어딘가 다른 데로 옮겨 줄 것처럼 덜 들렸으면 좋겠어요.
영어에서 번역·원문 보기Nope, and it's an easy map to make coming from Java. A Dart Future is a value that arrives later, not a thread. The whole app runs in one isolate, and that isolate has one thread running one event loop. On top of that, an async function runs synchronously until its first await. filterRows has no await inside, so the entire loop runs right there in the tap handler, before the Future is even returned. The frame that would draw the spinner sits in the event queue behind it. The rebuild after the await isn't the slow part, it doesn't even start until the loop is done.
Moving the work off that loop takes a second isolate.
import 'dart:isolate';
List<Entry> filterRows(List<Entry> rows, String query) =>
rows.where((r) => r.matches(query)).toList();
// in the tap handler
final result = await Isolate.run(() => filterRows(rows, query));
Now the await waits for a message from the other isolate, and the event loop is free in between. I do wish the keyword sounded less like it moves work somewhere else.