diff options
Diffstat (limited to 'mojo/public/python/mojo_bindings/promise.py')
-rw-r--r-- | mojo/public/python/mojo_bindings/promise.py | 196 |
1 files changed, 0 insertions, 196 deletions
diff --git a/mojo/public/python/mojo_bindings/promise.py b/mojo/public/python/mojo_bindings/promise.py deleted file mode 100644 index ebf6f85..0000000 --- a/mojo/public/python/mojo_bindings/promise.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -Promise used by the python bindings. - -The API is following the ECMAScript 6 API for promises. -""" - -import sys - - -class Promise(object): - """The promise object.""" - - STATE_PENDING = 0 - STATE_FULLFILLED = 1 - STATE_REJECTED = 2 - STATE_BOUND = 3 - - def __init__(self, generator_function): - """ - Constructor. - - Args: - generator_function: A function taking 2 arguments: resolve and reject. - When |resolve| is called, the promise is fullfilled with the given value. - When |reject| is called, the promise is rejected with the given value. - A promise can only be resolved or rejected once, all following calls will - have no effect. - """ - self._onCatched = [] - self._onFulfilled = [] - self._onRejected = [] - self._state = Promise.STATE_PENDING - self._result = None - try: - generator_function(self._Resolve, self._Reject) - except Exception as e: - # Adding traceback similarly to python 3.0 (pep-3134) - e.__traceback__ = sys.exc_info()[2] - self._Reject(e) - - @staticmethod - def Resolve(value): - """ - If value is a promise, make a promise that have the same behavior as value, - otherwise make a promise that fulfills to value. - """ - if isinstance(value, Promise): - return value - return Promise(lambda x, y: x(value)) - - @staticmethod - def Reject(reason): - "Make a promise that rejects to reason.""" - return Promise(lambda x, y: y(reason)) - - @staticmethod - def All(*iterable): - """ - Make a promise that fulfills when every item in the array fulfills, and - rejects if (and when) any item rejects. Each array item is passed to - Promise.resolve, so the array can be a mixture of promise-like objects and - other objects. The fulfillment value is an array (in order) of fulfillment - values. The rejection value is the first rejection value. - """ - def GeneratorFunction(resolve, reject): - state = { - 'rejected': False, - 'nb_resolved': 0, - } - promises = [Promise.Resolve(x) for x in iterable] - results = [None for x in promises] - def OnFullfilled(i): - def OnFullfilled(res): - if state['rejected']: - return - results[i] = res - state['nb_resolved'] = state['nb_resolved'] + 1 - if state['nb_resolved'] == len(results): - resolve(results) - return OnFullfilled - def OnRejected(reason): - if state['rejected']: - return - state['rejected'] = True - reject(reason) - - for (i, promise) in enumerate(promises): - promise.Then(OnFullfilled(i), OnRejected) - return Promise(GeneratorFunction) - - @staticmethod - def Race(*iterable): - """ - Make a Promise that fulfills as soon as any item fulfills, or rejects as - soon as any item rejects, whichever happens first. - """ - def GeneratorFunction(resolve, reject): - state = { - 'ended': False - } - def OnEvent(callback): - def OnEvent(res): - if state['ended']: - return - state['ended'] = True - callback(res) - return OnEvent - for promise in [Promise.Resolve(x) for x in iterable]: - promise.Then(OnEvent(resolve), OnEvent(reject)) - return Promise(GeneratorFunction) - - @property - def state(self): - if isinstance(self._result, Promise): - return self._result.state - return self._state - - def Then(self, onFullfilled=None, onRejected=None): - """ - onFulfilled is called when/if this promise resolves. onRejected is called - when/if this promise rejects. Both are optional, if either/both are omitted - the next onFulfilled/onRejected in the chain is called. Both callbacks have - a single parameter, the fulfillment value or rejection reason. |Then| - returns a new promise equivalent to the value you return from - onFulfilled/onRejected after being passed through Resolve. If an - error is thrown in the callback, the returned promise rejects with that - error. - """ - if isinstance(self._result, Promise): - return self._result.Then(onFullfilled, onRejected) - def GeneratorFunction(resolve, reject): - if self._state == Promise.STATE_PENDING: - self._onFulfilled.append(_Delegate(resolve, reject, onFullfilled)) - self._onRejected.append(_Delegate(reject, reject, onRejected)) - if self._state == self.STATE_FULLFILLED: - _Delegate(resolve, reject, onFullfilled)(self._result) - if self._state == self.STATE_REJECTED: - recover = reject - if onRejected: - recover = resolve - _Delegate(recover, reject, onRejected)(self._result) - return Promise(GeneratorFunction) - - def Catch(self, onCatched): - """Equivalent to |Then(None, onCatched)|""" - return self.Then(None, onCatched) - - def _Resolve(self, value): - if self.state != Promise.STATE_PENDING: - return - self._result = value - if isinstance(value, Promise): - self._state = Promise.STATE_BOUND - self._result.Then(_IterateAction(self._onFulfilled), - _IterateAction(self._onRejected)) - return - self._state = Promise.STATE_FULLFILLED - for f in self._onFulfilled: - f(value) - self._onFulfilled = None - self._onRejected = None - - def _Reject(self, reason): - if self.state != Promise.STATE_PENDING: - return - self._result = reason - self._state = Promise.STATE_REJECTED - for f in self._onRejected: - f(reason) - self._onFulfilled = None - self._onRejected = None - - -def _IterateAction(iterable): - def _Run(x): - for f in iterable: - f(x) - return _Run - - -def _Delegate(resolve, reject, action): - def _Run(x): - try: - if action: - resolve(action(x)) - else: - resolve(x) - except Exception as e: - # Adding traceback similarly to python 3.0 (pep-3134) - e.__traceback__ = sys.exc_info()[2] - reject(e) - return _Run |