Rename <Type>.from to <Type>.convert
[mootools.git] / Docs / Class / Class.Thenable.md
blobef8cfc0e707ec90d80e73502e1d7da9272a8c741
1 Class: Class.Thenable {#Class.Thenable}
2 =======================================
4 A Utility Class. Its methods can be implemented with [Class:implement][] into any [Class][].
5 It makes a Class "thenable" (see [Promises/A+][]), which means you can call its `then` method to integrate it in a [Promise][] style flow.
7 ### Syntax:
9 #### For new classes:
11         var MyClass = new Class({ Implements: Class.Thenable });
13 #### For existing classes:
15         MyClass.implement(Class.Thenable);
17 ### Implementing:
19 - This class can be implemented into other classes to add its functionality to them.
21 ### Example:
23         var Promise = new Class({
24                 Implements: Class.Thenable,
25                 initialize: function(executor){
26                         if (typeof executor !== 'function'){
27                                 throw new TypeError('Promise constructor takes a function argument.');
28                         }
30                         try {
31                                 executor(this.resolve.bind(this), this.reject.bind(this));
32                         } catch (exception){
33                                 this.reject(exception);
34                         }
35                 },
36                 resetThenable: function(){
37                         throw new TypeError('A promise can only be resolved once.');
38                 }
39         });
41         var myPromise = new Promise(function(resolve){
42                 resolve('Hello promised world!');
43         });
44         myPromise.then(function(value){
45                 console.log(value);
46         });
48 ### See Also:
50 - [Class][]
51 - [Promise][]
54 Class.Thenable Method: then {#Class.Thenable:then}
55 --------------------------------------------------
57 Registers callbacks to receive the class's eventual value or the reason why it cannot be succesfully resolved.
59 ### Syntax:
61         myClass.then(onFulfilled, onRejected);
63 ### Arguments:
65 1. onFulfilled - (*function*, optional) Function to execute when the value is succesfully resolved.
66 2. onRejected  - (*function*, optional) Function to execute when the value cannot be succesfully resolved.
68 ### Returns:
70 * (*object*) A new `Class.Thenable` instance that will have its value resolved based on the return values of the above mentioned arguments, compatible with [Promises/A+][].
72 ### Example:
74         var request = new Request();
75         request.send().then(function(response){ console.log(response); });
78 Class.Thenable Method: catch {#Class.Thenable:catch}
79 ----------------------------------------------------
81 Registers a callback to receive the reason why an eventual value cannot be succesfully resolved.
83 ### Syntax:
85         myClass.catch(onRejected);
87 ### Arguments:
89 1. onRejected  - (*function*, optional) Function to execute when the value cannot be succesfully resolved.
91 ### Returns:
93 * (*object*) A new `Class.Thenable` instance that will have its value resolved based on the return values of the above mentioned arguments, compatible with [Promises/A+][].
95 ### Example:
97         var request = new Request();
98         request.send().catch(function(reason){ console.log(reason); });
101 Class.Thenable Method: resolve {#Class.Thenable:resolve}
102 --------------------------------------------------------
104 Function to resolve the eventual value of the `Thenable`.
106 ### Syntax:
108         myClass.resolve(value);
110 ### Arguments:
112 1. value  - (*mixed*, optional) The value to resolve. If the value is "thenable" (like a [Promise][] or `Thenable`), it will be resolved with its eventual value (i.e. it will be resolved when the "thenable" is resolved).
114 ### Returns:
116 * (*object*) This Class instance.
118 ### Example:
120         var MyClass = new Class({
121                 Implements: Class.Thenable,
122                 initialize: function(){
123                         this.resolve('Hello world!');
124                 }
125         });
128 Class.Thenable Method: reject {#Class.Thenable:reject}
129 ------------------------------------------------------
131 Function to make a `Thenable` rejected, that is to say it will not receive an eventual value.
133 ### Syntax:
135         myClass.reject(reason);
137 ### Arguments:
139 1. reason  - (*mixed*, optional) The reason the `Thenable` will not be succesfully resolved, often an `Error` instance.
141 ### Returns:
143 * (*object*) This Class instance.
145 ### Example:
147         var MyClass = new Class({
148                 Implements: Class.Thenable,
149                 initialize: function(){
150                         this.reject(new Error('Cannot be succesfully resolved.'));
151                 }
152         });
155 Class.Thenable Method: getThenableState {#Class.Thenable:getThenableState}
156 --------------------------------------------------------------------------
158 Returns the state of the `Thenable` Class.
160 ### Syntax:
162         myClass.getThenableState();
164 ### Returns:
166 * (*string*) The current state: "pending", "fulfilled" or "rejected".
168 ### Example:
170         var MyClass = new Class({
171                 Implements: Class.Thenable,
172                 initialize: function(){
173                         console.log(this.getThenableState());
174                 }
175         });
178 Class.Thenable Method: resetThenable {#Class.Thenable:resetThenable}
179 --------------------------------------------------------------------
181 Resets the state of the `Thenable` Class, to make it usable multiple times. If the current `Thenable` state was not resolved yet, it will be rejected first and the `onRejected` handlers will be executed.
183 Use with caution, this is not in line with [Promise][] behaviour: a once resolved `Thenable` can be resolved with a different value after it is reset. Useful in case a Class can intentionally receive resolved values multiple times, e.g. a `Request` instance that can be executed multiple times or an `Fx` instance that is used multiple times.
185 ### Syntax:
187         myClass.resetThenable(reason);
189 ### Arguments:
191 1. reason  - (*mixed*, optional) The reason to pass when rejecting a currently unresolved state.
193 ### Returns:
195 * (*object*) This Class instance.
197 ### Example:
199         var MyClass = new Class({
200                 Implements: Class.Thenable,
201                 initialize: function(){
202                         var self = this;
203                         this.addEvent('start', function(){
204                                 self.resetThenable();
205                         });
206                 }
207         });
209 ### Note: {#Class.Thenable:resetThenable-note}
211 Take care when using [Chain][] and `Class.Thenable` together. When multiple resolutions are chained, the registration of callbacks for later resolutions has to be chained as well. Since `myClass.chain()` returns the class instance, `myClass.chain(fn).then(callback)` is equivalent to `myClass.chain(fn); myClass.then(callback)`, and so the callback is not chained to whatever `fn` does.
213 To use `chain`, you can use one of the following patterns:
215         myClass.start().chain(function(){ this.start() }).chain(function(){ this.then(callback); });
216         myClass.start().chain(function(){ this.start().then(callback); });
218 If your aim is to use a Promise style flow, you should probably not use `chain`, and just use `then` instead:
220         myClass.start().then(function(){ return myClass.start(); }).then(callback);
223 [Chain]: /core/Class/Class.Extras#Chain
224 [Class]: /core/Class/Class
225 [Class:implement]: /core/Class/Class/#Class:implement
226 [Promise]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
227 [Promises/A+]: https://promisesaplus.com/