aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/javascript/reference/statements/async_function/index.html
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
commit218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch)
treea9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/web/javascript/reference/statements/async_function/index.html
parent074785cea106179cb3305637055ab0a009ca74f2 (diff)
downloadtranslated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip
initial commit
Diffstat (limited to 'files/zh-tw/web/javascript/reference/statements/async_function/index.html')
-rw-r--r--files/zh-tw/web/javascript/reference/statements/async_function/index.html163
1 files changed, 163 insertions, 0 deletions
diff --git a/files/zh-tw/web/javascript/reference/statements/async_function/index.html b/files/zh-tw/web/javascript/reference/statements/async_function/index.html
new file mode 100644
index 0000000000..ced67f4a09
--- /dev/null
+++ b/files/zh-tw/web/javascript/reference/statements/async_function/index.html
@@ -0,0 +1,163 @@
+---
+title: async function
+slug: Web/JavaScript/Reference/Statements/async_function
+tags:
+ - JavaScript
+ - 函式
+ - 實驗
+ - 範例
+ - 陳述
+translation_of: Web/JavaScript/Reference/Statements/async_function
+---
+<div>{{jsSidebar("Statements")}}</div>
+
+<p><code><strong>async function</strong></code> 宣告被定義為一個回傳 {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}} 物件的<em>非同步函式</em> 。</p>
+
+<div class="noinclude">
+<p>你也可以使用 {{jsxref("Operators/async_function", "async function expression", "", 1)}} 來定義一個<em>非同步函式</em>。</p>
+</div>
+
+<h2 id="語法">語法</h2>
+
+<pre class="syntaxbox">async function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
+ <em>statements</em>
+}
+</pre>
+
+<h3 id="參數">參數</h3>
+
+<dl>
+ <dt><code>name</code></dt>
+ <dd>函式名稱。</dd>
+</dl>
+
+<dl>
+ <dt><code>param</code></dt>
+ <dd>傳遞至函式的參數名稱。</dd>
+</dl>
+
+<dl>
+ <dt><code>statements</code></dt>
+ <dd>組成該函式主體的陳述。</dd>
+</dl>
+
+<h3 id="回傳值">回傳值</h3>
+
+<p>{{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}} 物件,代表著一個非同步函式,該函式會執行該函式內的程式碼。</p>
+
+<h2 id="描述">描述</h2>
+
+<p>當 <code>async</code> 函式被呼叫時,它會回傳一個 {{jsxref("Promise")}}。如果該 <code>async</code> 函式回傳了一個值,<code>Promise</code> 的狀態將為一個帶有該回傳值的 resolved。如果 <code>async</code> 函式拋出例外或某個值,<code>Promise</code> 的狀態將為一個帶有被拋出值的 rejected。</p>
+
+<p>async 函式內部可以使用 {{jsxref("Operators/await", "await")}} 表達式,它會暫停此 async 函式的執行,並且等待傳遞至表達式的 Promise 的解析,解析完之後會回傳解析值,並繼續此 async 函式的執行。</p>
+
+<div class="note">
+<p><code>async/await</code> 函式的目的在於簡化同步操作 promise 的表現,以及對多個 <code>Promise</code> 物件執行某些操作。就像 <code>Promise 類似於具結構性的回呼函式,同樣地,async/await 好比將 generator 與 promise 組合起來。</code></p>
+</div>
+
+<h2 id="範例">範例</h2>
+
+<h3 id="簡單範例">簡單範例</h3>
+
+<pre class="brush: js">function resolveAfter2Seconds(x) {
+ return new Promise(resolve =&gt; {
+ setTimeout(() =&gt; {
+ resolve(x);
+ }, 2000);
+ });
+}
+
+
+async function add1(x) {
+ const a = await resolveAfter2Seconds(20);
+ const b = await resolveAfter2Seconds(30);
+ return x + a + b;
+}
+
+add1(10).then(v =&gt; {
+ console.log(v); // prints 60 after 4 seconds.
+});
+
+
+async function add2(x) {
+ const p_a = resolveAfter2Seconds(20);
+ const p_b = resolveAfter2Seconds(30);
+ return x + await p_a + await p_b;
+}
+
+add2(10).then(v =&gt; {
+ console.log(v); // prints 60 after 2 seconds.
+});
+</pre>
+
+<div class="warning">
+<h4 id="不要誤解_Promise.all_的_await">不要誤解 <code>Promise.all</code> 的 <code>await</code></h4>
+
+<p>在 <code>add1</code> 裡,該執行為了第一個 <code>await</code> 而暫停了兩秒,接著為了第二個 <code>await</code> 又暫停了兩秒。在第一個計時器(timer)被觸發前,第二個計時器並不會被建立。而在 <code>add2</code> 裡,兩個計時器都被建立起來、也都執行 <code>await</code> 過了。這把它帶往了 resolve 所的 2 秒暫停、而不是 4 秒暫停。然而這兩個 <code>await</code> 呼叫都在連續運行,而非平行運行。<code>await</code> <strong>並不是</strong> <code>Promise.all</code> 的自動程式。如果你想讓兩個、甚至兩個以上的 <code>await</code> promises 同時執行(in parallel),你必須使用 <code>Promise.all</code>.</p>
+</div>
+
+<h3 id="使用_async_function_改寫_promise_鏈">使用 async function 改寫 promise 鏈</h3>
+
+<p>一個 API 呼叫所回傳的 {{jsxref("Promise")}} 會導致一個 promise 鏈,將函式分隔成多個部份。考慮下列的程式碼:</p>
+
+<pre class="brush: js">function getProcessedData(url) {
+ return downloadData(url) // returns a promise
+ .catch(e =&gt; {
+ return downloadFallbackData(url); // returns a promise
+ })
+ .then(v =&gt; {
+ return processDataInWorker(v); // returns a promise
+ });
+}
+</pre>
+
+<p>它可以用一個簡單的 <code>async function</code> 來改寫成這樣:</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>注意上方的範例,在 return 陳述中沒有使用 await 陳述,這是因為 async function 的回傳值隱含地被包裝於 {{jsxref("Promise.resolve")}} 之中。</p>
+
+<h2 id="規範">規範</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">規範</th>
+ <th scope="col">狀態</th>
+ <th scope="col">註解</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>
+ </tbody>
+</table>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<div>
+
+
+<p>{{Compat("javascript.statements.async_function")}}</p>
+</div>
+
+<h2 id="參見">參見</h2>
+
+<ul>
+ <li>{{jsxref("Operators/async_function", "async function expression")}}</li>
+ <li>{{jsxref("AsyncFunction")}} 物件</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>