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
|
---
title: yield
slug: Web/JavaScript/Reference/Operators/yield
tags:
- ECMAScript 2015
- Generators
- Iterator
- JavaScript
- Operator
translation_of: Web/JavaScript/Reference/Operators/yield
---
<div>{{jsSidebar("Operators")}}</div>
<p><code>yield</code> 关键字用来暂停和恢复一个生成器函数(({{jsxref("Statements/function*", "function*")}} 或<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">遗留的生成器函数</a>)。</p>
<h2 id="Syntax" name="Syntax">语法</h2>
<pre class="syntaxbox">[<em>rv</em>] = <strong>yield</strong> [<em>expression</em>];</pre>
<dl>
<dt><code>expression</code></dt>
<dd>定义通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">迭代器协议</a>从生成器函数返回的值。如果省略,则返回<code>undefined</code>。</dd>
<dt><code>rv</code></dt>
<dd>
<p>返回传递给生成器的<code>next()</code>方法的可选值,以恢复其执行。</p>
</dd>
</dl>
<h2 id="描述">描述</h2>
<p><code>yield</code>关键字使生成器函数执行暂停,<code>yield</code>关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的<code>return</code>关键字。</p>
<p><code>yield</code>关键字实际返回一个<code>IteratorResult</code>对象,它有两个属性,<code>value</code>和<code>done</code>。<code>value</code>属性是对<code>yield</code>表达式求值的结果,而<code>done</code>是<code>false</code>,表示生成器函数尚未完全完成。</p>
<p>一旦遇到 <code>yield</code> 表达式,生成器的代码将被暂停运行,直到生成器的 <code>next()</code> 方法被调用。每次调用生成器的<code>next()</code>方法时,生成器都会恢复执行,直到达到以下某个值:</p>
<ul>
<li><code>yield</code>,导致生成器再次暂停并返回生成器的新值。 下一次调用<code>next()</code>时,在<code>yield</code>之后紧接着的语句继续执行。</li>
<li>{{jsxref("Statements/throw", "throw")}}用于从生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,正如通常情况下抛出异常一样。</li>
<li>到达生成器函数的结尾;在这种情况下,生成器的执行结束,并且<code>IteratorResult</code>给调用者返回{{jsxref("undefined")}}并且<code>done</code>为<code>true</code>。</li>
<li>到达{{jsxref("Statements/return", "return")}} 语句。在这种情况下,生成器的执行结束,并将<code>IteratorResult</code>返回给调用者,其值是由<code>return</code>语句指定的,并且<code>done</code> 为<code>true</code>。</li>
</ul>
<p>如果将参数传递给生成器的<code>next()</code>方法,则该值将成为生成器当前<code>yield</code>操作返回的值。</p>
<p>在生成器的代码路径中的<code>yield</code>运算符,以及通过将其传递给{{jsxref("Generator.prototype.next()")}}指定新的起始值的能力之间,生成器提供了强大的控制力。</p>
<h2 id="Examples" name="Examples">示例</h2>
<p>以下代码是一个生成器函数的声明。</p>
<pre class="brush: js">function* countAppleSales () {
var saleList = [3, 7, 5];
for (var i = 0; i < saleList.length; i++) {
yield saleList[i];
}
}</pre>
<p>一旦生成器函数已定义,可以通过构造一个迭代器来使用它。</p>
<pre class="brush: js">var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }</pre>
<h2 id="Specifications" name="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('ES2015', '#', 'Yield')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Initial definition.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#', 'Yield')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">浏览器兼容性</h2>
<p>{{Compat("javascript.operators.yield")}}</p>
<h2 id="See_also" name="See_also">相关链接</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol">The Iterator protocol</a></li>
<li>{{jsxref("Statements/function*", "function*")}}</li>
<li>{{jsxref("Operators/function*", "function* expression")}}</li>
<li>{{jsxref("Operators/yield*", "yield*")}}</li>
</ul>
|