Python Forum
Thread Rating:
  • 2 Vote(s) - 2.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Promise
#3
Wait wait wait.  It makes more sense for the Promise itself to handle threading, since almost anything that uses it would involve threading anyway.

import threading


class STATES:
    Pending = 0
    Resolved = 1
    Rejected = 2


class Promise:
    def __init__(self, worker):
        keys = [STATES.Resolved, STATES.Rejected]

        self.state = STATES.Pending
        self.callbacks = {key: [] for key in keys}
        self.content = {key: None for key in keys}

        def callback_generator(state):
            def callback(response=None):
                self.content[state] = response
                self.state = state
                self.__run(state)
            return callback

        self._lock = threading.Lock()
        self._thread = threading.Thread(target=worker, args=(
            callback_generator(STATES.Resolved),
            callback_generator(STATES.Rejected)))
        self._thread.start()

    def join(self):
        with self._lock:
            self._thread.join()

    def __run(self, key):
        # a callback is only ever called a single time
        with self._lock:
            while self.callbacks[key]:
                callback = self.callbacks[key].pop(0)
                # chain the output of one callback into the input of the next
                response = callback(self.content[key])
                if response is not None:
                    self.content[key] = response

    def __chain_method(self, state, callback):
        with self._lock:
            self.callbacks[state].append(callback)

            # register the new promise's callbacks with the parent, so data/errors
            # will chain
            def worker(resolve, fail):
                self.callbacks[STATES.Resolved].append(resolve)
                self.callbacks[STATES.Rejected].append(fail)

            future = Promise(worker)
            future.content = self.content
            future.state = self.state
            if self.state == state:
                self.__run(state)

            return future

    def then(self, callback):
        return self.__chain_method(STATES.Resolved, callback)

    def catch(self, callback):
        return self.__chain_method(STATES.Rejected, callback)


import time


def delayed(delay):
    def runner(resolved, failed):
        time.sleep(delay)
        resolved()

    return Promise(runner)


if __name__ == "__main__":
    def callback(*args):
        print("Inside callback")

    print("Before delayed callback")
    future = delayed(2.5).then(callback)
    print("After delayed callback")
    for _ in range(5):
        print("waiting...")
        time.sleep(1)
    future.join()
Output:
Before delayed callback After delayed callback waiting... waiting... waiting... Inside callback waiting... waiting...
Reply


Messages In This Thread
Promise - by nilamo - Aug-16-2017, 04:09 AM
RE: Promise - by nilamo - Aug-17-2017, 08:44 PM
RE: Promise - by nilamo - Aug-18-2017, 09:36 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020