Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / third_party / Promises / README.md
1 #### NOTE: The IDL hosted here is now advisory. This repo hosts refactoring examples and designs, a high-fidelity polyfill, and rationale for this work. [See the living DOM spec for the current version](http://dom.spec.whatwg.org/#futures) if you are implementing Promises in a runtime.
2
3 <img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
4      align="right" alt="Promises/A+ logo, since DOMFutures are compatible" />
5
6 # DOM Promises
7
8 A Promises Design for DOM, currently in IDL. Also a p(r)ollyfill
9 and re-worked APIs to take advantage of the new semantics.
10
11 ## Promises? [I Don't Speak Your Crazy Moon Language](http://www.pigdog.org/auto/mr_bads_list/shortcolumn/1914.html).
12
13 A Promise is an object that implements a standard contract for
14 the results of an operation that may have already occurred or may happen in the
15 future.
16
17 There's a lot in that sentence that's meaningful, but the big ticket items are:
18
19   * Promises are a contract for _a single result_, either success or failure. If
20     you need to model something that happens multiple times, a single Future is
21     not the answer (try events or an iterator that creates a stream of Promises).
22   * Promises provide a mechanism for multiple parties to be informed of a value,
23     much the same way many bits of code can hold a reference to a variable
24     without knowing about each other.
25   * Promises aren't, in themselves notable. Instead, they derive their value
26     through being _the one way_ to encapsulate potentially asynchronous return
27     values.
28
29 To do all of this without syntax support from the language, Promises must be
30 objects with standardized methods. The current design provides a constructable 
31 class that allows end-user code to vend instances of `Future` from their own APIs 
32 as well as a few standard methods:
33
34 ```js
35 // Accepts "accept" and "reject" callbacks, roughly the same thing as success
36 // and failure for the operation.
37 futureInstance.then(onaccept, onreject);
38
39 // Accept and reject callbacks only ever have a single parameter, which is the
40 // value or reason, respectively:
41 futureInstance.then(
42   function(value) {
43     doSomethingWithTheResult(value);
44   },
45   function(reason) { console.error(reason); }
46 );
47
48 // .then() always returns a new Future, one which takes whatever value the
49 // callback it's registered with returns:
50 futureInstance.then(function(value) {
51                 return processValue(value);
52               })
53               .then(function(processedValue) {
54                 // ...
55               });
56
57 // A key part of the Futures design is that these operations are *chainable*,
58 // even for asynchronous code. This makes it easy to compose asynchronous
59 // operations in readable, linear-looking code:
60 futureInstance.then(aHandlerThatReturnsAFuture)
61               .then(doSomethingAfterTheSecondCallback);
62
63 // .catch() gives you access only to errors:
64 futureInstance.catch(onreject);
65 ```
66
67 ## OK, So Why Promises For DOM?
68
69 To understand why DOM needs Futures, think about a few of the asynchronous APIs
70 in DOM that return single values:
71
72   * [XHR](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
73   * [Geolocation](http://www.w3.org/TR/geolocation-API/)
74   * [IndexedDB](http://www.w3.org/TR/IndexedDB/)
75   * [`onload`](https://developer.mozilla.org/en-US/docs/DOM/window.onload)
76
77 There are some similarities today in how these APIs work. XHR and `onload` share 
78 the idea of a `readyState` property to let code detect if something has happened 
79 in the past, giving rise to logic like this:
80
81 ```js
82 if (document.readyState == "complete") {
83   doStartupWork();
84 } else {
85   document.addEventListener("load", doStartupWork, false);
86 }
87 ```
88
89 This is cumbersome and error-prone, not to mention ugly. IndexedDB's
90 [`IDBRequest` class](https://developer.mozilla.org/en-US/docs/IndexedDB/IDBRequest) 
91 also supports a `readyState` property, but the values range from 
92 [1-2](https://developer.mozilla.org/en-US/docs/IndexedDB/IDBRequest#readyState_constants), 
93 not [0-4 as used in XHR](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#Properties) 
94 or [strings as used for documents](http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#current-document-readiness). 
95 Making matters worse, the callback and event names don't even match! Clearly 
96 DOM needs a better way to do things.
97
98 A uniform interface would allow us to manage our callbacks sanely across APIs:
99
100 ```js
101 // Example of what the future might hold, not in any current spec
102 document.ready().then(doStartupWork);
103
104 // By returning a Future subclass, XHR's send() method gets more usable too:
105 var xhr = new XMLHttpRequest();
106 xhr.open("GET", filename, true);
107 xhr.send().then(handleSuccessfulResponse,
108                 handleErrorResponse);
109
110 // Geolocation can be easily refactored too:
111 navigator.geolocation.getCurrentPosition().then(successCallback, errorCallback);
112
113 // Even IDB gets saner:
114 indexedDB.open(databaseName).then(function(db) {
115   // ...
116 });
117 ```
118
119 Providing a single abstraction for this sort of operation creates cross-cutting
120 value across specifications, making it easier to use DOM and simpler for
121 libraries to interoperate based on a standard design.
122
123 ## OK, But Aren't You Late To This Party?
124
125 There's a [long, long history of Promises](http://en.wikipedia.org/wiki/Futures_and_promises)
126 both inside and outside JavaScript. Many other languages provide them via
127 language syntax or standard library. Promises are such a common pattern inside
128 JavaScript that nearly all major libraries provide some form them and vend 
129 them for many common operations which they wrap. There are  differences in 
130 terminology and use, but the core ideas are mostly the same be they 
131 [jQuery Deferreds](http://api.jquery.com/category/deferred-object/), 
132 [WinJS Promises](http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx), 
133 [Dojo Deferreds or Promises](http://dojotoolkit.org/documentation/tutorials/1.6/promises/), 
134 [Cujo Promises](https://github.com/cujojs/when), 
135 [Q Promises](https://github.com/kriskowal/q/wiki/API-Reference), [RSVP Promises (used heavily in Ember)](https://github.com/tildeio/rsvp.js), or even in [Node Promises](https://github.com/kriszyp/node-promise). The diversity of implementations has led both to incompatibility and efforts to standardize, the most promising of which is the [Promises/A+ effort](https://github.com/promises-aplus/promises-spec), which of course differs slightly from [Promises/A](http://wiki.commonjs.org/wiki/Promises/A) and greatly from [other pseudo-standard variants proposed over the years](http://wiki.commonjs.org/wiki/Promises). 
136
137 Promises/A+ doesn't define all of the semantics needed for a full implementation, 
138 and if we assume DOM needs Promises, it will also need an answer to those 
139 questions. That's what this repository is about.
140
141 ## More Examples
142
143 ```js
144 // New APIs that vend Futures are easier to reason about. Instead of:
145 if (document.readyState == "complete") {
146   doStartupWork();
147 } else {
148   document.addEventListener("load", doStartupWork, false);
149 }
150
151 // ...a Future-vending ready() method can be used at any time:
152 document.ready().then(doStartupWork);
153
154 // Like other Promises-style APIs, .then() and .done() are the
155 // primary way to work with Futures, including via chaining, in
156 // this example using an API proposed at:
157 //    https://github.com/slightlyoff/async-local-storage
158 var storage = navigator.storage;
159 storage.get("item 1").then(function(item1value) {
160   return storage.set("item 1", "howdy");
161 }).
162 done(function() {
163   // The previous future is chained to not resolve until
164   //item 1 is set to "howdy"
165   storage.get("item 1").done(console.log);
166 });
167 ```
168
169 Promises can also be new'd up and used in your own APIs, making them a powerful
170 abstraction for building asynchronous contracts for single valued operations;
171 basically any time you want to do some work asynchronously but only care about
172 a single response value:
173
174 ```js
175 function fetchJSON(filename) {
176   // Return a Promise that represents the fetch:
177   return new Promise(function(resolver){
178     // The resolver is how a Promise is satisfied. It has reject(), fulfill(),
179     // and resolve() methods that your code can use to inform listeners with:
180     var xhr = new XMLHttpRequest();
181     xhr.open("GET", filename, true);
182     xhr.send();
183     xhr.onreadystatechange = function() {
184       if (xhr.readyState == 4) {
185         try {
186           resolver.resolve(JSON.parse(xhr.responseText));
187         } catch(e) {
188           resolver.reject(e);
189         }
190       }
191     }
192   });
193 }
194
195 // Now we can use the uniform Future API to reason about JSON fetches:
196 fetchJSON("thinger.json").then(function(object) { ... } ,
197                                function(error) { ... });
198 ```