8.13. Sterowanie pętlą#
Większość skryptów asyncio nigdy nie dotyka bezpośrednio pętli zdarzeń – asyncio.run() wystarcza. Ta strona omawia interfejs Loop dla przypadków, gdy to nie wystarcza: instalowania obsługi wyjątków, uruchamiania pętli z innym cyklem życia niż run lub przechowywania obiektu pętli na potrzeby instrumentacji.
8.13.1. Pobieranie pętli#
asyncio.get_event_loop()– zwraca obiektLoop. Można go bezpiecznie wywołać zarówno wewnątrz, jak i na zewnątrz korutyny.asyncio.new_event_loop()– w MicroPython resetuje stan istniejącej pętli, zamiast tworzyć nową. Warto powtórzyć uwagę: w programie istnieje dokładnie jedna pętla zdarzeń.
Nie ma API do uruchamiania pętli innego niż metody klasy Loop oraz asyncio.run().
8.13.2. Bezpośrednie uruchamianie pętli#
asyncio.run() to właściwy punkt wejścia dla niemal każdej aplikacji. Dla przypadków, gdy nim nie jest, istnieją dwie metody Loop.
run_until_complete()– mając dany obiekt awaitable, uruchamia pętlę do momentu jego zakończenia, a następnie zwraca jego wynik. Odpowiednik pojedynczego wywołaniaasyncio.run(), z pominięciem zburzenia pętli.run_forever()– uruchamia pętlę, dopóki nie zostanie wywołanestop()z wnętrza zadania. Brak obiektu awaitable najwyższego poziomu; oczekuje się, że aplikacja zaplanuje to, czego potrzebuje, za pomocąasyncio.create_task()przed wywołaniemrun_forever.
Metodami towarzyszącymi są stop() (żądanie zatrzymania pętli po zakończeniu bieżącego zadania) oraz close() (zwolnienie zasobów pętli).
8.13.3. Tworzenie zadań po stronie pętli#
create_task()– ta sama operacja coasyncio.create_task(). Wolna funkcja istnieje, aby kod aplikacji nie potrzebował referencji do pętli w typowym przypadku; metoda istnieje na potrzeby instrumentacji, która już ją posiada.
8.13.4. Obsługa wyjątków#
Pętla wywołuje funkcję obsługi, gdy zadanie zgłasza wyjątek, którego nic w łańcuchu wywołań korutyny nie przechwyciło – typowym przypadkiem jest zadanie utworzone przez aplikację za pomocą asyncio.create_task(), na które nigdy nie wykonano await. Domyślna funkcja obsługi wypisuje ślad stosu przez sys.stderr; strona o wyjątkach pokazała, jak podmienić ją na coś niestandardowego.
set_exception_handler()– instaluje niestandardową funkcję obsługi. Funkcja obsługi to obiekt wywoływalnyhandler(loop, context), gdziecontextjest słownikiem zawierającym co najmniej'message', a zazwyczaj również'exception'i'future'.get_exception_handler()– zwraca aktualnie zainstalowaną funkcję obsługi lubNone, jeśli używana jest domyślna.default_exception_handler()– wbudowana funkcja obsługi. Przydatna wewnątrz niestandardowej funkcji obsługi, która chce również wykonać domyślne zachowanie (na przykład zapisać do pamięci flash oraz wypisać ślad stosu).call_exception_handler()– uruchamia aktualnie zainstalowaną funkcję obsługi z ręcznie zbudowanym słownikiem kontekstu. Używane głównie przez samą pętlę; aplikacja rzadko tego potrzebuje.