How do I write a sequence of promises in Python?
Solution 1
Here's a similar program using asyncio and the async/await
syntax:
import asyncio
import random
async def alpha(x):
await asyncio.sleep(0.2)
return x + 1
async def bravo(x):
await asyncio.sleep(0.2)
return random.randint(0, 1000) + x
async def charlie(x):
if x % 2 == 0:
return x
raise ValueError(x, 'is odd')
async def run():
try:
number = await charlie(await bravo(await alpha(42)))
except ValueError as exc:
print('error:', exc.args[0])
else:
print('success:', number)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
EDIT: If you're interested in reactive streams, you might consider using aiostream.
Here's a simple example:
import asyncio
from aiostream import stream, pipe
async def main():
# This stream computes 11² + 13² in 1.5 second
xs = (
stream.count(interval=0.1) # Count from zero every 0.1 s
| pipe.skip(10) # Skip the first 10 numbers
| pipe.take(5) # Take the following 5
| pipe.filter(lambda x: x % 2) # Keep odd numbers
| pipe.map(lambda x: x ** 2) # Square the results
| pipe.accumulate() # Add the numbers together
)
print('11² + 13² = ', await xs)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
More examples in the documentation.
Disclaimer: I am the project maintainer.
Solution 2
You're in luck, Python 3.4 and above include asyncio
, although the feature you are looking for (Future) is available in Python 3.5 and up.
From your own link about asyncio
: "This version is only relevant for Python 3.3, which does not include asyncio in its stdlib."
Example:
import asyncio
async def some_coroutine():
await asyncio.sleep(1)
return 'done'
def process_result(future):
print('Task returned:', future.result())
loop = asyncio.get_event_loop()
task = loop.create_task(some_coroutine())
task.add_done_callback(process_result)
loop.run_until_complete()
JP Ventura
An independent and self-motivated professional with excellent research and and data-oriented development.
Updated on January 26, 2022Comments
-
JP Ventura over 2 years
Is it possible to write a sequence of promise (or tasks) using only Python 3.6.1 Standard Library?
For example, a sequence promises in JavaScript is written as:
const SLEEP_INTERVAL_IN_MILLISECONDS = 200; const alpha = function alpha (number) { return new Promise(function (resolve, reject) { const fulfill = function() { return resolve(number + 1); }; return setTimeout(fulfill, SLEEP_INTERVAL_IN_MILLISECONDS); }); }; const bravo = function bravo (number) { return new Promise(function (resolve, reject) { const fulfill = function() { return resolve(Math.ceil(1000*Math.random()) + number); }; return setTimeout(fulfill, SLEEP_INTERVAL_IN_MILLISECONDS); }); }; const charlie = function charlie (number) { return new Promise(function (resolve, reject) { return (number%2 == 0) ? reject(number) : resolve(number); }); }; function run() { return Promise.resolve(42) .then(alpha) .then(bravo) .then(charlie) .then((number) => { console.log('success: ' + number) }) .catch((error) => { console.log('error: ' + error); }); } run();
Each function also returns a Promise with asynchronous processing result, that would be resolved/rejected by the immediately following promise.
I am aware of libraries such as
promises-2.01b
andasyncio 3.4.3
and I am looking for a Python STL solution. Thus, if I need to import a non-STL library, I prefer using RxPython instead. -
JP Ventura about 7 yearsHow would you translate the previous JS example into Python 3.5 using Future?
-
JP Ventura about 7 yearsCool! The only bad part is the telescopic method invocation. As hoping to write something more like a JS promise sequence or reactive observable stream. But this one already solves my problems :-)
-
Vincent about 7 years@JPVentura Yes, this line is a bit long but you can split it up by using extra variables. asyncio doesn't have a pipe syntax because it tries to be as close to synchronous programing as possible Also, see my edit about reactive streams.
-
Shlomi Schwartz over 5 years@Vincent, could you please have a look here: stackoverflow.com/questions/53466252/…
-
yota almost 3 yearsinteresting ! but are calls to "callback" asynchronous ?
-
fontno over 2 yearsOutside of the scared to try new things or just too lazy to learn (which is crazy for devs, but I see it all the time), how can you not love functional style stream pipes...