Verwenden Sie das Asyncio-Modul für asynchrone Anforderungen in Python. Schreiben wir Code, der die API asynchron mit dem Anforderungspaket trifft.
API
Ich hätte time.sleep ()
verwenden können, aber dieses Mal werde ich ein Muster annehmen, um die API zu erhalten, anstatt zu üben.
Ich habe "JSON Placeholder" als Mock-Server verwendet.
Schreiben Sie den Code, der die APIs (6 unten) auffordert, die Liste synchron und asynchron abzurufen, und geben Sie das Ergebnis jedes Ergebnisses in einer Liste zurück.
https://jsonplaceholder.typicode.com/posts https://jsonplaceholder.typicode.com/comments https://jsonplaceholder.typicode.com/albums https://jsonplaceholder.typicode.com/photos https://jsonplaceholder.typicode.com/todos https://jsonplaceholder.typicode.com/users
Lassen Sie uns zunächst eine Anfrage im synchronen Prozess stellen. Wenn Sie es gemäß dem üblichen Python-Code schreiben, sieht es wie folgt aus.
import time
import requests
BASE_URL = "https://jsonplaceholder.typicode.com/"
def calc_time(fn):
"""Dekorateur, der die Ausführungszeit einer Funktion misst"""
def wrapper(*args, **kwargs):
start = time.time()
fn(*args, **kwargs)
end = time.time()
print(f"[{fn.__name__}] elapsed time: {end - start}")
return
return wrapper
def get_sync(path: str) -> dict:
print(f"/{path} request")
res = requests.get(BASE_URL + path)
print(f"/{path} request done")
return res.json()
@calc_time
def main_sync():
data_ls = []
paths = [
"posts",
"comments",
"albums",
"photos",
"todos",
"users",
]
for path in paths:
data_ls.append(get_sync(path))
return data_ls
if __name__ == "__main__":
main_sync()
Beim Ausführen erhalten Sie eine Ausgabe ähnlich der folgenden:
Anfrage 1-> Anfrage 1 abgeschlossen Anfrage 2-> Anfrage 2 abgeschlossen Anfrage 3-> Anfrage 3 abgeschlossen ...
Sie können sehen, dass es ausgeführt wird.
/posts request
/posts request done
/comments request
/comments request done
/albums request
/albums request done
/photos request
/photos request done
/todos request
/todos request done
/users request
/users request done
[main_sync] elapsed time: 1.157785415649414
Stellen Sie dann eine asynchrone Anforderung.
Asynchron ausgeführte Aufgaben werden innerhalb einer Ereignisschleife ausgeführt. Verwenden Sie zum Abrufen der Ereignisschleife "asyncio.get_event_loop ()".
loop.run_until_complete
ist, wie der Name schon sagt, eine Methode, die eine Ereignisschleife ausführt, bis jede Aufgabe ausgeführt wurde.
Der Rückgabewert dieser Methode ist eine Liste, die den Rückgabewert jeder asynchronen Ausführungsaufgabe enthält.
Die Ausführungsreihenfolge ist nicht garantiert, aber die Rückgabewerte werden in der an das Argument übergebenen Reihenfolge zurückgegeben, sodass sie auch dann verwendet werden können, wenn die Reihenfolge wichtig ist.
Das mit async def deklarierte get_async wird als Collout-Funktion bezeichnet. Der Ausdruck "Warten" innerhalb einer Coroutine-Funktion wird angehalten, bis der Rückgabewert der Ausführung der Coroutine-Funktion erreicht ist.
import asyncio
#Korroutinenfunktion
async def get_async(path: str) -> dict:
print(f"/{path} async request")
url = BASE_URL + path
loop = asyncio.get_event_loop()
#In Ereignisschleife ausführen
res = await loop.run_in_executor(None, requests.get, url)
print(f"/{path} async request done")
return res.json()
@calc_time
def main_async():
#Ereignisschleife abrufen
loop = asyncio.get_event_loop()
#Asynchrone Ausführungsaufgabe in einem zukünftigen Objekt
tasks = asyncio.gather(
get_async("posts"),
get_async("comments"),
get_async("albums"),
get_async("photos"),
get_async("todos"),
get_async("users"),
)
#Asynchrone Ausführung, bis jede beendet ist
results = loop.run_until_complete(tasks)
return results
if __name__ == "__main__":
main_async()
Die Ausgabe sieht folgendermaßen aus:
Anfrage 1 Anfrage 2 Anfrage 3 ... Anfrage 1 erledigt Anfrage 2 erledigt Anfrage 3 erledigt ...
Sie können sehen, dass es verarbeitet wird. Sie können auch sehen, dass die Ausführungszeit erheblich reduziert wurde.
/posts async request
/comments async request
/albums async request
/photos async request
/todos async request
/users async request
/users async request done
/todos async request done
/posts async request done
/albums async request done
/comments async request done
/photos async request done
[main_async] elapsed time: 0.17921733856201172
Recommended Posts