Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a sequence of promises in Python?

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 and asyncio 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.

like image 697
JP Ventura Avatar asked Apr 10 '17 14:04

JP Ventura


People also ask

How do you execute a promise in a sequence?

The essence of this function is to use reduce starting with an initial value of Promise. resolve([]) , or a promise containing an empty array. This promise will then be passed into the reduce method as promise . This is the key to chaining each promise together sequentially.

How do you write a promise in Python?

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( ...

Does promise all run sequentially?

all() method executed by taking promises as input in the single array and executing them sequentially.

Does promise all resolve promises in order?

Here, Promise. all() method is the order of the maintained promises. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.


2 Answers

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.

like image 83
Vincent Avatar answered Oct 01 '22 00:10

Vincent


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() 
like image 34
Wolph Avatar answered Oct 01 '22 00:10

Wolph