aboutsummaryrefslogtreecommitdiff
path: root/files/he/web/javascript/reference/global_objects/promise/index.html
blob: 1f1c71827cfdaa9830e4386ea3ca8d917a828972 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
---
title: Promise
slug: Web/JavaScript/Reference/Global_Objects/Promise
translation_of: Web/JavaScript/Reference/Global_Objects/Promise
---
<div>{{JSRef}}</div>

<p>The <strong><code>Promise</code></strong> object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.</p>

<div class="note">
<p><strong>Note:</strong> This article describes the <code>Promise</code> constructor and the methods and properties of such objects. To learn about the way promises work and how you can use them, we advise you to read <a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using promises</a> first. The constructor is primarily used to wrap functions that do not already support promises.</p>
</div>

<div>{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}</div>

<p class="hidden">The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>

<h2 id="תחביר">תחביר</h2>

<pre class="brush: js">new Promise( /* executor */ function(resolve, reject) { ... } );</pre>

<h3 id="פרמטרים">פרמטרים</h3>

<dl>
 <dt>executor</dt>
 <dd>A function that is passed with the arguments <code>resolve</code> and <code>reject</code>. The <code>executor</code> function is executed immediately by the Promise implementation, passing <code>resolve</code> and <code>reject</code> functions (the executor is called before the <code>Promise</code> constructor even returns the created object). The <code>resolve</code> and <code>reject</code> functions, when called, resolve or reject the promise, respectively. The executor normally initiates some asynchronous work, and then, once that completes, either calls the <code>resolve</code> function to resolve the promise or else rejects it if an error occurred. If an error is thrown in the executor function, the promise is rejected. The return value of the executor is ignored.</dd>
</dl>

<h2 id="תיאור">תיאור</h2>

<p>A <code><strong>Promise</strong></code> is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a <em>promise</em> to supply the value at some point in the future.</p>

<p>A <code>Promise</code> is in one of these states:</p>

<ul>
 <li><em>pending</em>: initial state, neither fulfilled nor rejected.</li>
 <li><em>fulfilled</em>: meaning that the operation completed successfully.</li>
 <li><em>rejected</em>: meaning that the operation failed.</li>
</ul>

<p>A pending promise can either be <em>fulfilled</em> with a value, or <em>rejected</em> with a reason (error). When either of these options happens, the associated handlers queued up by a promise's <code>then</code> method are called. (If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.)</p>

<p>As the <code>{{jsxref("Promise.then", "Promise.prototype.then()")}}</code> and <code>{{jsxref("Promise.catch", "Promise.prototype.catch()")}}</code> methods return promises, they can be chained.</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/15911/promises.png" style="height: 297px; width: 801px;"></p>

<div class="note">
<p><strong>Not to be confused with:</strong> Several other languages have mechanisms for lazy evaluation and deferring a computation, which they also call "promises", e.g. Scheme. Promises in JavaScript represent processes which are already happening, which can be chained with callback functions. If you are looking to lazily evaluate an expression, consider the <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow function</a> with no arguments: <code>f = () =&gt; <em>expression</em></code> to create the lazily-evaluated expression, and <code>f()</code> to evaluate.</p>
</div>

<div class="note">
<p><strong>Note</strong>: A promise is said to be <em>settled</em> if it is either fulfilled or rejected, but not pending. You will also hear the term <em>resolved</em> used with promises — this means that the promise is settled or “locked in” to match the state of another promise. <a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md">States and fates</a> contains more details about promise terminology.</p>
</div>

<h2 id="מאפיינים">מאפיינים</h2>

<dl>
 <dt><code>Promise.length</code></dt>
 <dd>Length property whose value is always 1 (number of constructor arguments).</dd>
 <dt>{{jsxref("Promise.prototype")}}</dt>
 <dd>Represents the prototype for the <code>Promise</code> constructor.</dd>
</dl>

<h2 id="Methods">Methods</h2>

<dl>
 <dt>{{jsxref("Promise.all", "Promise.all(iterable)")}}</dt>
 <dd>Returns a promise that either fulfills when all of the promises in the iterable argument have fulfilled or rejects as soon as one of the promises in the iterable argument rejects. If the returned promise fulfills, it is fulfilled with an array of the values from the fulfilled promises in the same order as defined in the iterable. If the returned promise rejects, it is rejected with the reason from the first promise in the iterable that rejected. This method can be useful for aggregating results of multiple promises.</dd>
 <dt>{{jsxref("Promise.race", "Promise.race(iterable)")}}</dt>
 <dd>Returns a promise that fulfills or rejects as soon as one of the promises in the iterable fulfills or rejects, with the value or reason from that promise.</dd>
 <dt>{{jsxref("Promise.reject", "Promise.reject(reason)")}}</dt>
 <dd>Returns a <code>Promise</code> object that is rejected with the given reason.</dd>
 <dt>{{jsxref("Promise.resolve", "Promise.resolve(value)")}}</dt>
 <dd>Returns a <code>Promise</code> object that is resolved with the given value. If the value is a thenable (i.e. has a <code>then</code> method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value. Generally, if you don't know if a value is a promise or not, {{jsxref("Promise.resolve", "Promise.resolve(value)")}} it instead and work with the return value as a promise.</dd>
</dl>

<h2 id="Promise_prototype">Promise prototype</h2>

<h3 id="Properties">Properties</h3>

<p>{{page('en-US/Web/JavaScript/Reference/Global_Objects/Promise/prototype','Properties')}}</p>

<h3 id="Methods_2">Methods</h3>

<p>{{page('en-US/Web/JavaScript/Reference/Global_Objects/Promise/prototype','Methods')}}</p>

<h2 id="Creating_a_Promise">Creating a Promise</h2>

<p>A <code>Promise</code> object is created using the <code>new </code>keyword and its constructor. This constructor takes as its argument a function, called the "executor function". This function should take two functions as parameters. The first of these functions (<code>resolve</code>) is called when the asynchronous task completes successfully and returns the results of the task as a value. The second (<code>reject</code>) is called when the task fails, and returns the reason for failure, which is typically an error object.</p>

<pre class="brush: js">const myFirstPromise = new Promise((resolve, reject) =&gt; {
  // do something asynchronous which eventually calls either:
  //
  //   resolve(someValue); // fulfilled
  // or
  //   reject("failure reason"); // rejected
});
</pre>

<p>To provide a function with promise functionality, simply have it return a promise:</p>

<pre class="brush: js">function myAsyncFunction(url) {
  return new Promise((resolve, reject) =&gt; {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () =&gt; resolve(xhr.responseText);
    xhr.onerror = () =&gt; reject(xhr.statusText);
    xhr.send();
  });
}</pre>

<h2 id="דוגמאות">דוגמאות</h2>

<h3 id="דוגמה_בסיסית">דוגמה בסיסית</h3>

<pre class="brush: js">let myFirstPromise = new Promise((resolve, reject) =&gt; {
  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code.
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout(function(){
    resolve("Success!"); // Yay! Everything went well!
  }, 250);
});

myFirstPromise.then((successMessage) =&gt; {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage);
});
</pre>

<h3 id="דוגמה_מתקדמת">דוגמה מתקדמת</h3>

<pre class="brush: html hidden">&lt;button id="btn"&gt;Make a promise!&lt;/button&gt;
&lt;div id="log"&gt;&lt;/div&gt;
</pre>

<p>This small example shows the mechanism of a <code>Promise</code>. The <code>testPromise()</code> method is called each time the {{HTMLElement("button")}} is clicked. It creates a promise that will be fulfilled, using {{domxref("window.setTimeout()")}}, to the promise count (number starting from 1) every 1-3 seconds, at random. The <code>Promise()</code> constructor is used to create the promise.</p>

<p>The fulfillment of the promise is simply logged, via a fulfill callback set using {{jsxref("Promise.prototype.then()","p1.then()")}}. A few logs show how the synchronous part of the method is decoupled from the asynchronous completion of the promise.</p>

<pre class="brush: js">'use strict';
var promiseCount = 0;

function testPromise() {
    let thisPromiseCount = ++promiseCount;

    let log = document.getElementById('log');
    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Started (&lt;small&gt;Sync code started&lt;/small&gt;)&lt;br/&gt;');

    // We make a new promise: we promise a numeric count of this promise, starting from 1 (after waiting 3s)
    let p1 = new Promise(
        // The executor function is called with the ability to resolve or
        // reject the promise
       (resolve, reject) =&gt; {
            log.insertAdjacentHTML('beforeend', thisPromiseCount +
                ') Promise started (&lt;small&gt;Async code started&lt;/small&gt;)&lt;br/&gt;');
            // This is only an example to create asynchronism
            window.setTimeout(
                function() {
                    // We fulfill the promise !
                    resolve(thisPromiseCount);
                }, Math.random() * 2000 + 1000);
        }
    );

    // We define what to do when the promise is resolved with the then() call,
    // and what to do when the promise is rejected with the catch() call
    p1.then(
        // Log the fulfillment value
        function(val) {
            log.insertAdjacentHTML('beforeend', val +
                ') Promise fulfilled (&lt;small&gt;Async code terminated&lt;/small&gt;)&lt;br/&gt;');
        }).catch(
        // Log the rejection reason
       (reason) =&gt; {
            console.log('Handle rejected promise ('+reason+') here.');
        });

    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Promise made (&lt;small&gt;Sync code terminated&lt;/small&gt;)&lt;br/&gt;');
}</pre>

<pre class="brush:js hidden">if ("Promise" in window) {
  let btn = document.getElementById("btn");
  btn.addEventListener("click",testPromise);
} else {
  log = document.getElementById('log');
  log.innerHTML = "Live example not available as your browser doesn't support the &lt;code&gt;Promise&lt;code&gt; interface.";
}
</pre>

<p>This example is started by clicking the button. You need a browser that supports <code>Promise</code>. By clicking the button several times in a short amount of time, you'll even see the different promises being fulfilled one after another.</p>

<p>{{EmbedLiveSample("Advanced_Example", "500", "200")}}</p>

<h2 id="טעינת_תמונה_באמצעות_XHR">טעינת תמונה באמצעות XHR</h2>

<p>Another simple example using <code>Promise</code> and {{domxref("XMLHttpRequest")}} to load an image is available at the MDN GitHub <a href="https://github.com/mdn/js-examples/tree/master/promises-test">js-examples</a> repository. You can also <a href="https://mdn.github.io/js-examples/promises-test/">see it in action</a>. Each step is commented and allows you to follow the Promise and XHR architecture closely.</p>

<h2 id="מפרט">מפרט</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-promise-objects', 'Promise')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Initial definition in an ECMA standard.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
 </tbody>
</table>

<h2 id="תאימות_דפדפן">תאימות דפדפן</h2>

<p class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p>

<p>{{Compat("javascript.builtins.Promise")}}</p>

<h2 id="ראה_גם">ראה גם</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using promises</a></li>
 <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li>
 <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li>
 <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li>
 <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li>
 <li><a href="http://www.html5rocks.com/en/tutorials/es6/promises/">Jake Archibald: JavaScript Promises: There and Back Again</a></li>
 <li><a href="http://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript">Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript</a></li>
 <li><a href="http://www.mattgreer.org/articles/promises-in-wicked-detail/">Matt Greer: JavaScript Promises ... In Wicked Detail</a></li>
 <li><a href="https://www.promisejs.org/">Forbes Lindesay: promisejs.org</a></li>
 <li><a href="https://github.com/jakearchibald/es6-promise/">Promise polyfill</a></li>
 <li><a href="https://www.udacity.com/course/javascript-promises--ud898">Udacity: JavaScript Promises</a></li>
</ul>