diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:49:24 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:49:24 +0100 |
commit | de5c456ebded0e038adbf23db34cc290c8829180 (patch) | |
tree | 2819c07a177bb7ec5f419f3f6a14270d6bcd7fda /files/pl/web/javascript/reference/statements/async_function/index.html | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-de5c456ebded0e038adbf23db34cc290c8829180.tar.gz translated-content-de5c456ebded0e038adbf23db34cc290c8829180.tar.bz2 translated-content-de5c456ebded0e038adbf23db34cc290c8829180.zip |
unslug pl: move
Diffstat (limited to 'files/pl/web/javascript/reference/statements/async_function/index.html')
-rw-r--r-- | files/pl/web/javascript/reference/statements/async_function/index.html | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/files/pl/web/javascript/reference/statements/async_function/index.html b/files/pl/web/javascript/reference/statements/async_function/index.html new file mode 100644 index 0000000000..95b488405e --- /dev/null +++ b/files/pl/web/javascript/reference/statements/async_function/index.html @@ -0,0 +1,264 @@ +--- +title: funkcja async +slug: Web/JavaScript/Referencje/Polecenia/funkcja_async +translation_of: Web/JavaScript/Reference/Statements/async_function +--- +<div> +<div>{{jsSidebar("Statements")}}</div> + +<p><span class="seoSummary">Deklaracja funkcji <code><strong>async</strong></code> definiuje <strong>funkcję asynchroniczną</strong>, która zwraca obiekt {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}.</span> Funkcja asynchroniczna to funkcja, która działa asynchroniczne poprzez zdarzenie pętli używając bezwarunkowego {{jsxref("Promise")}} do zwrócenia wyniku. Składnia i struktura kodu używanego przy funkcjach asynchronicznych jest jednakże bardziej podobna do znanych ze standardowych funkcji synchronicznych.</p> + +<div class="noinclude"> +<p>Możesz zdefiniować funkcje asynchroniczne również poprzez użycie {{jsxref("Operators/async_function", "async function expression", "", 1)}}.</p> +</div> +</div> + +<div>{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}</div> + +<p class="hidden">Źródło niniejszego interaktywnego demo znajduje się na repozytorium GitHuba. Jeśli chcesz mieć wkład w ten interaktywny projekt demo po prostu sklonuj <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> i wyślij nam żądanie pull.</p> + +<h2 id="Składnia">Składnia</h2> + +<pre class="syntaxbox">async function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<h3 id="Parametry">Parametry</h3> + +<dl> + <dt><code>name</code></dt> + <dd>Nazwa funkcji.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>Nazwa argumentu, który zostanie podany do funkcji.</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>Wyrażenia stanowiące ciało funkcji.</dd> +</dl> + +<h3 id="Wartość_zwrotna_return">Wartość zwrotna (return)</h3> + +<p><code><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>, które zostanie rozwiązane z wartością zwróconą przez funkcję asynchroniczną lub odrzucone z nieprzechwyconym wyjątkiem wyrzuconym z funkcji asynchronicznej.</p> + +<h2 id="Opis">Opis</h2> + +<p>Funkcja <code>async</code> może zawierać wyrażenie {{jsxref("Operators/await", "await")}}, które wstrzymuje wywołanie funkcji asynchronicznej i czeka na przekazaną deklarację <code>Promise</code>i wtedy wznawia wywołanie funkcji <code>async</code> oraz interpretuje jako wartość rozwiązaną.<br> + <br> + Pamiętaj, że polecenie <code>await</code> działa wyłącznie wewnątrz funkcji <code>async</code>. Jeśli użyjesz go poza ciałem funkcji <code>async</code> otrzymasz <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a></code>.</p> + +<p>Zauważ, że kiedy funkcja <code>async</code> jest wstrzymana, funkcja wywołująca kontynuuje działanie (otrzymując domyślny Promise zwracany przez funkcję <code>async</code>).</p> + +<div class="note"> +<p>Celem funkcji <code>async</code>/<code>await</code> jest uproszczenie działania używając obietnic (promises) synchronicznie oraz by wykonać pewne działania w grupie <code>Promises</code>. Tak, jak <code>Promises</code> są podobne do strukturalnych callbacków, tak <code>async</code>/<code>await</code> jest podobne do kombinacji generatorów i obietnic.</p> +</div> + +<h2 id="Przykłady">Przykłady</h2> + +<h3 id="Prosty_przykład">Prosty przykład</h3> + +<pre class="brush: js">var resolveAfter2Seconds = function() { + console.log("starting slow promise"); + return new Promise(resolve => { + setTimeout(function() { + resolve("slow"); + console.log("wolna obietnica została wykonana"); + }, 2000); + }); +}; + +var resolveAfter1Second = function() { + console.log("starting fast promise"); + return new Promise(resolve => { + setTimeout(function() { + resolve("fast"); + console.log("szybka obietnica została wykonana"); + }, 1000); + }); +}; + +var sequentialStart = async function() { + console.log('==START SEKWENCYJNY=='); + + // 1. Niemalże natychmiast dochodzi do wywołania + const slow = await resolveAfter2Seconds(); + console.log(slow); // 2. to zostaje wywołanie 2s po 1. + + const fast = await resolveAfter1Second(); + console.log(fast); // 3. to zostaje wykonane 3s po 1. +} + +var concurrentStart = async function() { + console.log('==RÓWNOCZESNY START z await=='); + const slow = resolveAfter2Seconds(); // licznik startuje od razu + const fast = resolveAfter1Second(); // licznik startuje od razu + + // 1. Niemalże natychmiast dochodzi do wywołania + console.log(await slow); // 2. jest wywołane 2s po 1. + console.log(await fast); // 3. jest wywołane 2s po 1., natychmiast po 2., podczas gdy szybka jest już wykonana +} + +var concurrentPromise = function() { + console.log('==RÓWNOCZESNY START z Promise.all=='); + return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => { + console.log(messages[0]); // wolne + console.log(messages[1]); // szybkie + }); +} + +var parallel = async function() { + console.log('==RÓWNOLEGLE z await Promise.all=='); + + // Równolegle startują dwa zadania i czekamy na zakończenie działania obu + await Promise.all([ + (async()=>console.log(await resolveAfter2Seconds()))(), + (async()=>console.log(await resolveAfter1Second()))() + ]); +} + +// This function does not handle errors. See warning below! +var parallelPromise = function() { + console.log('==PARALLEL with Promise.then=='); + resolveAfter2Seconds().then((message)=>console.log(message)); + resolveAfter1Second().then((message)=>console.log(message)); +} + +sequentialStart(); // after 2 seconds, logs "slow", then after 1 more second, "fast" + +// wait above to finish +setTimeout(concurrentStart, 4000); // after 2 seconds, logs "slow" and then "fast" + +// wait again +setTimeout(concurrentPromise, 7000); // same as concurrentStart + +// wait again +setTimeout(parallel, 10000); // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow" + +// wait again +setTimeout(parallelPromise, 13000); // same as parallel +</pre> + +<div class="note"> +<h4 id="await_and_parallelism"><code>await</code> and parallelism</h4> + +<p>In <code>sequentialStart</code>, execution suspends 2 seconds for the first <code>await</code>, and then again another 1 second for the second <code>await</code>. The second timer is not created until the first has already fired. The code finishes after 3 seconds.</p> + +<p>In <code>concurrentStart</code>, both timers are created and then <code>await</code>ed. The timers are running concurrently, which means the code finishes in 2 rather than 3 seconds, i.e. the slowest timer.<br> + However the <code>await</code> calls are still running in series, which means the second <code>await</code> will wait for the first one to finish. In this case, this leads to the processing of the result of the fastest timer to be performed after the slowest.</p> + +<p>If you wish to fully perform two or more jobs in parallel, you must use <code>await Promise.all([job1(), job2()])</code> as shown in the <code>parallel</code> example.</p> +</div> + +<div class="warning"> +<h4 id="asyncawait_vs_Promisethen_and_error_handling"><code>async</code>/<code>await</code> vs Promise#then and error handling</h4> + +<p>Most async functions can also be written as regular functions using Promises. However <code>async</code> functions are a little bit less error-prone when it comes to error handling.</p> + +<p>Both <code>concurrentStart</code> and <code>concurrentPromise</code> are functionally equivalent.<br> + In <code>concurrentStart</code>, if either of the <code>await</code>ed calls fail, the exception will be automatically caught, the async function execution interrupted, and the Error propagated to the caller through the implicit return Promise.<br> + For the same to happen in the Promise case, the function must take care of returning a <code>Promise</code> which captures the completion of the function. In <code>concurrentPromise</code> that means <code>return</code>ing the promise from <code>Promise.all([]).then()</code>. As a matter of fact, a previous version of this example forgot to do this!</p> + +<p>It is however still possible for <code>async</code> functions to mistakenly swallow errors.<br> + Take for example the <code>parallel</code> async function. If it didn't <code>await</code> (or <code>return</code>) the result of the <code>Promise.all([])</code> call, any Error would not have been propagated.<br> + While the <code>parallelPromise</code> example seem simple, it does not handle errors at all! Doing so would require a similar <code>return </code><code>Promise.all([])</code>.</p> +</div> + +<h3 id="Rewriting_a_promise_chain_with_an_async_function">Rewriting a promise chain with an <code>async</code> function</h3> + +<p>An API that returns a {{jsxref("Promise")}} will result in a promise chain, and it splits the function into many parts. Consider the following code:</p> + +<pre class="brush: js">function getProcessedData(url) { + return downloadData(url) // returns a promise + .catch(e => { + return downloadFallbackData(url); // returns a promise + }) + .then(v => { + return processDataInWorker(v); // returns a promise + }); +} +</pre> + +<p>it can be rewritten with a single <code>async</code> function as follows:</p> + +<pre class="brush: js">async function getProcessedData(url) { + let v; + try { + v = await downloadData(url); + } catch(e) { + v = await downloadFallbackData(url); + } + return processDataInWorker(v); +} +</pre> + +<p>Note that in the above example, there is no <code>await</code> statement on the <code>return</code> statement, because the return value of an <code>async function</code> is implicitly wrapped in {{jsxref("Promise.resolve")}}.</p> + +<div class="blockIndicator note"> +<h4 id="return_await_promiseValue_vs._return_promiseValue"><code>return await promiseValue;</code> vs. <code>return promiseValue;</code></h4> + +<p>The implicit wrapping of return values in {{jsxref("Promise.resolve")}} does not imply that <code>return await promiseValue;</code> is functionally equivalent to <code>return promiseValue;</code></p> + +<p>Consider the following rewrite of the above code that returns null if <code>processDataInWorker</code> were to reject with an error:</p> + +<pre class="brush: js">async function getProcessedData(url) { + let v; + try { + v = await downloadData(url); + } catch(e) { + v = await downloadFallbackData(url); + } + try { + return await processDataInWorker(v); // Note the `return await` vs. just `return` + } catch (e) { + return null; + } +} +</pre> + +<p>Having simply written <code>return processDataInWorker(v);</code> would have caused the {{jsxref("Promise")}} returned by the function to reject instead of resolving to <code>null</code> in the case where <code>processDataInWorker(v)</code> rejects. This highlights the subtle difference between <code>return foo;</code> and <code>return await foo;</code> which is that <code>return foo;</code> will immediately return <code>foo</code> and never throw even if <code>foo</code> is a promise and rejects whereas <code>return await foo;</code> will wait for <code>foo</code> to resolve or reject if it's a promise and will throw <strong>before returning</strong> if it rejects.</p> +</div> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Initial definition in ES2017.</td> + </tr> + <tr> + <td>{{SpecName('ES8', '#sec-async-function-definitions', 'async function')}}</td> + <td>{{Spec2('ES8')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div> + + +<p>{{Compat("javascript.statements.async_function")}}</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Operators/async_function", "async function expression")}}</li> + <li>{{jsxref("AsyncFunction")}} object</li> + <li>{{jsxref("Operators/await", "await")}}</li> + <li><a href="http://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/">"Decorating Async Javascript Functions" on "innolitics.com"</a></li> +</ul> |