Flet 앱은 비동기 앱으로 작성할 수 있으며 asyncio 및 기타 Python 비동기 라이브러리를 사용할 수 있다. 코루틴 호출은 Flet에서 자연스럽게 지원되므로 동기적으로 실행하기 위해 코루틴(coroutine)을 래핑할 필요가 없다.
기본적으로 Flet은 별도의 스레드에서 컨트롤 이벤트 핸들러를 실행하지만, 때로는 비효율적으로 CPU를 사용하거나 HTTP 응답을 기다리거나 sleep()을 실행하는 동안 아무 작업도 하지 않을 수 있다.
반면 asyncio는 '코루틴' 간에 실행 컨텍스트를 전환하여 단일 스레드에서 동시성을 구현할 수 있다. 이는 Pyodide를 사용하여 정적 웹사이트로 게시하려는 앱에 특히 중요하다. Pyodide는 웹어셈블리(WASM)로 빌드되어 브라우저에서 실행되는 Python 런타임이다.
Flet앱의 main함수에 async를 붙여 asyncio API를 사용할 수 있다.
import flet as ft
async def main(page: ft.Page):
await asyncio.sleep(1)
page.add(ft.Text("Hello, async world!"))
ft.app(main)
이벤트핸들러는 동기 또는 비동기가 될 수 있다.
def page_resize(e):
print("New page size:", page.window_width, page.window_height)
page.on_resize = page_resize
핸들러가 비동기함수를 사용한다면 비동기가 된다.
async def main(page: ft.Page):
async def button_click(e):
await some_async_method()
page.add(ft.Text("Hello!"))
page.add(ft.ElevatedButton("Say hello!", on_click=button_click))
ft.app(main)
비동기 lambda함수라는 건 없다. 비동기앱에서 람다이벤트핸들러는 가질 수 있다.
page.on_error = lambda e: print("Page error:", e.data)
비동기 앱에서 코드실행을 지연하려면 ascyncio.sleep를 사용해야 한다.
import asyncio
import flet as ft
def main(page: ft.Page):
async def button_click(e):
await asyncio.sleep(1)
page.add(ft.Text("Hello!"))
page.add(
ft.ElevatedButton("Say hello with delay!", on_click=button_click)
)
ft.app(main)
백그라운드로 뭔가 실행하려면 pahe.run_task()를 사용한다. 예를 들어 백그라운드로 스스로 자신을 업데이트하는 Countdown커스텀 컨트톨을 다음과 같이 구현할 수 있다.
import asyncio
import flet as ft
class Countdown(ft.Text):
def __init__(self, seconds):
super().__init__()
self.seconds = seconds
def did_mount(self):
self.running = True
self.page.run_task(self.update_timer)
def will_unmount(self):
self.running = False
async def update_timer(self):
while self.seconds and self.running:
mins, secs = divmod(self.seconds, 60)
self.value = "{:02d}:{:02d}".format(mins, secs)
self.update()
await asyncio.sleep(1)
self.seconds -= 1
def main(page: ft.Page):
page.add(Countdown(120), Countdown(60))
ft.app(main)
