Reputation: 325
I am trying to understand what would be the best code structure or a design pattern that would do the following:
Have a function named get_data
that would start up a socket connection and will start waiting for a specific socket event that would return some data. Once it gets the data, only then the get_data
function should be returned.
So in JS it would be very simple like this:
(Keep in mind that this code snippet is an example, it's not meant to be a working code)
const getData = async ()=>{
return new Promise((resolve, reject)=>{
const socket = socket()
socket.on("message", (data)=>{
resolve(data)
})
socket.connect("localhost")
});
}
const parseData = async () => {
const data = await getData()
// do something with the data
}
With Python however, I have absolutely no idea how to achieve the same result.
How would I translate it to Python? What strategy would be used here?
The only way I could think of right now is like this:
def get_data():
socket = socket()
my_data = None
@socket.event
def message(data):
nonlocal my_data
my_data = data
socket.connect("localhost")
while not my_data:
time.sleep(0.3)
socket.disconnect()
return my_data
def parse_data():
data = get_data()
# do something with the data
Upvotes: 9
Views: 5557
Reputation: 27218
If you want to convert a callback-based API into an async
API, you’re probably looking for asyncio.Future
.
Modifying your strawman code a bit:
import asyncio
def get_data():
# create a future
future = asyncio.Future()
# create a socket
socket = socket()
# connect callbacks
@socket.on("message")
def on_message(data):
future.set_result(data)
@socket.on("error")
def on_error(error):
future.set_exception(error)
# create a background task that will communicate with the socket
# and invoke the callbacks
@asyncio.create_task
async def communicate():
socket.connect('localhost')
socket.communicate()
# return the future
return future
Calling get_data
will return an object you can await
on just like async
function calls:
async def parse_data():
data = await get_data()
# process further
Upvotes: 10