Auto status change to "Under Review"
@@ -0,0 +1,48 | |||
|
1 | using System; | |
|
2 | using System.Diagnostics; | |
|
3 | ||
|
4 | namespace Implab { | |
|
5 | public class Deferred<T> : IResolvable<T> { | |
|
6 | readonly AbstractPromise<T> m_promise; | |
|
7 | readonly IDispatcher m_dispatcher; | |
|
8 | ||
|
9 | internal Deferred(AbstractPromise<T> promise, IDispatcher dispatcher) { | |
|
10 | Debug.Assert(promise != null); | |
|
11 | m_promise = promise; | |
|
12 | m_dispatcher = dispatcher; | |
|
13 | } | |
|
14 | ||
|
15 | public IPromise<T> Promise { | |
|
16 | get { return m_promise; } | |
|
17 | } | |
|
18 | ||
|
19 | public void Reject(Exception error) { | |
|
20 | m_promise.Reject(error); | |
|
21 | } | |
|
22 | ||
|
23 | public void Resolve(T value) { | |
|
24 | m_promise.Resolve(value); | |
|
25 | } | |
|
26 | ||
|
27 | public void Resolve(IPromise<T> thenable) { | |
|
28 | if (thenable == null) | |
|
29 | Reject(new Exception("The promise or task are expected")); | |
|
30 | if (thenable == m_promise) | |
|
31 | Reject(new Exception("The promise cannot be resolved with oneself")); | |
|
32 | ||
|
33 | else if (m_dispatcher != null) | |
|
34 | // dispatch (see ecma-262/6.0: 25.4.1.3.2 Promise Resolve Functions) | |
|
35 | m_dispatcher.Enqueue(() => Chain(thenable)); | |
|
36 | else | |
|
37 | Chain(thenable); | |
|
38 | } | |
|
39 | ||
|
40 | void Chain(IPromise<T> thenable) { | |
|
41 | try { | |
|
42 | thenable.Then(this); | |
|
43 | } catch (Exception err) { | |
|
44 | Reject(err); | |
|
45 | } | |
|
46 | } | |
|
47 | } | |
|
48 | } No newline at end of file |
@@ -0,0 +1,11 | |||
|
1 | using System; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | ||
|
5 | public interface IResolvable<T> { | |
|
6 | void Resolve(T value); | |
|
7 | ||
|
8 | void Reject(Exception reason); | |
|
9 | ||
|
10 | } | |
|
11 | } No newline at end of file |
@@ -0,0 +1,35 | |||
|
1 | using System; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | public class PromiseReaction : IResolvable { | |
|
5 | IDispatcher m_dispatcher; | |
|
6 | ||
|
7 | Action m_onFulfilledJob; | |
|
8 | ||
|
9 | Action<Exception> m_onRejectedJob; | |
|
10 | ||
|
11 | IResolvable m_next; | |
|
12 | ||
|
13 | public void Reject(Exception error) { | |
|
14 | if (m_onRejectedJob != null) { | |
|
15 | if (m_dispatcher != null) | |
|
16 | m_dispatcher.Enqueue(() => m_onRejectedJob(error)); | |
|
17 | else | |
|
18 | m_onRejectedJob(error); | |
|
19 | } else { | |
|
20 | m_next.Reject(error); | |
|
21 | } | |
|
22 | } | |
|
23 | ||
|
24 | public void Resolve() { | |
|
25 | if (m_onRejectedJob != null) { | |
|
26 | if (m_dispatcher != null) | |
|
27 | m_dispatcher.Enqueue( m_onFulfilledJob); | |
|
28 | else | |
|
29 | m_onFulfilledJob(); | |
|
30 | } else { | |
|
31 | m_next.Resolve(); | |
|
32 | } | |
|
33 | } | |
|
34 | } | |
|
35 | } No newline at end of file |
@@ -0,0 +1,103 | |||
|
1 | using System; | |
|
2 | using System.Diagnostics; | |
|
3 | ||
|
4 | namespace Implab | |
|
5 | { | |
|
6 | class PromiseReactionJob { | |
|
7 | public static Action<T> Create<T>(Action<T> handler, Deferred next) { | |
|
8 | Debug.Assert(handler != null); | |
|
9 | ||
|
10 | return (v) => { | |
|
11 | try { | |
|
12 | handler(v); | |
|
13 | next.Resolve(); | |
|
14 | } catch(Exception err) { | |
|
15 | next.Reject(err); | |
|
16 | } | |
|
17 | }; | |
|
18 | } | |
|
19 | ||
|
20 | public static Action<T> Create<T>(Func<T, IPromise> handler, Deferred next) { | |
|
21 | Debug.Assert(handler != null); | |
|
22 | ||
|
23 | return (v) => { | |
|
24 | try { | |
|
25 | next.Resolve(handler(v)); | |
|
26 | } catch(Exception err) { | |
|
27 | next.Reject(err); | |
|
28 | } | |
|
29 | }; | |
|
30 | } | |
|
31 | ||
|
32 | public static Action<T> Create<T,T2>(Func<T, T2> handler, Deferred<T2> next) { | |
|
33 | Debug.Assert(handler != null); | |
|
34 | ||
|
35 | return (v) => { | |
|
36 | try { | |
|
37 | next.Resolve(handler(v)); | |
|
38 | } catch(Exception err) { | |
|
39 | next.Reject(err); | |
|
40 | } | |
|
41 | }; | |
|
42 | } | |
|
43 | ||
|
44 | public static Action<T> Create<T,T2>(Func<T, IPromise<T2>> handler, Deferred<T2> next) { | |
|
45 | Debug.Assert(handler != null); | |
|
46 | return (v) => { | |
|
47 | try { | |
|
48 | next.Resolve(handler(v)); | |
|
49 | } catch(Exception err) { | |
|
50 | next.Reject(err); | |
|
51 | } | |
|
52 | }; | |
|
53 | } | |
|
54 | ||
|
55 | public static Action Create(Action handler, Deferred next) { | |
|
56 | Debug.Assert(handler != null); | |
|
57 | ||
|
58 | return () => { | |
|
59 | try { | |
|
60 | handler(); | |
|
61 | next.Resolve(); | |
|
62 | } catch(Exception err) { | |
|
63 | next.Reject(err); | |
|
64 | } | |
|
65 | }; | |
|
66 | } | |
|
67 | ||
|
68 | public static Action Create(Func<IPromise> handler, Deferred next) { | |
|
69 | Debug.Assert(handler != null); | |
|
70 | ||
|
71 | return () => { | |
|
72 | try { | |
|
73 | next.Resolve(handler()); | |
|
74 | } catch(Exception err) { | |
|
75 | next.Reject(err); | |
|
76 | } | |
|
77 | }; | |
|
78 | } | |
|
79 | ||
|
80 | public static Action Create<T2>(Func<T2> handler, Deferred<T2> next) { | |
|
81 | Debug.Assert(handler != null); | |
|
82 | ||
|
83 | return () => { | |
|
84 | try { | |
|
85 | next.Resolve(handler()); | |
|
86 | } catch(Exception err) { | |
|
87 | next.Reject(err); | |
|
88 | } | |
|
89 | }; | |
|
90 | } | |
|
91 | ||
|
92 | public static Action Create<T2>(Func<IPromise<T2>> handler, Deferred<T2> next) { | |
|
93 | Debug.Assert(handler != null); | |
|
94 | return () => { | |
|
95 | try { | |
|
96 | next.Resolve(handler()); | |
|
97 | } catch(Exception err) { | |
|
98 | next.Reject(err); | |
|
99 | } | |
|
100 | }; | |
|
101 | } | |
|
102 | } | |
|
103 | } No newline at end of file |
@@ -0,0 +1,25 | |||
|
1 | using System; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | public class PromiseReaction<T> : IResolvable<T> { | |
|
5 | IDispatcher m_dispatcher; | |
|
6 | ||
|
7 | Action<T> m_onFulfilledJob; | |
|
8 | ||
|
9 | Action<Exception> m_onRejectedJob; | |
|
10 | ||
|
11 | public void Reject(Exception error) { | |
|
12 | if (m_dispatcher != null) | |
|
13 | m_dispatcher.Enqueue(() => m_onRejectedJob(error)); | |
|
14 | else | |
|
15 | m_onRejectedJob(error); | |
|
16 | } | |
|
17 | ||
|
18 | public void Resolve(T result) { | |
|
19 | if (m_dispatcher != null) | |
|
20 | m_dispatcher.Enqueue(() => m_onFulfilledJob(result)); | |
|
21 | else | |
|
22 | m_onFulfilledJob(result); | |
|
23 | } | |
|
24 | } | |
|
25 | } No newline at end of file |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now