esma标准_了解JavaScript中的生成器-> ESMA脚本

esma标准

In ECMAScript 2015, generators were introduced to the JavaScript language. A generator is a process that can be paused and resumed and can yield multiple values. A generator in JavaScript consists of a generator function, which returns an iterable Generator object.

ECMAScript 2015中生成器被引入JavaScript语言。 生成器是可以暂停和恢复并可以产生多个值的过程。 JavaScript中的生成器包含一个生成器函数 ,该函数返回一个可迭代的Generator对象。

In this article, we’ll cover how to create generator functions, how to iterate over Generator objects, the difference between yield and return inside a generator, and other aspects of working with generators.

在本文中,我们将介绍如何创建生成器函数,如何迭代Generator对象, Generator内部yieldreturn之间的差异以及使用生成器的其他方面。

发电机功能 (Generator Functions)

A generator function is a function that returns a Generator object, and is defined by the function keyword followed by an asterisk (*), as shown in the following:

生成器函数是一个返回Generator对象的函数,由function关键字定义,后跟一个星号( * ),如下所示:

// Generator function declaration
function* generatorFunction() {}

Occasionally, you will see the asterisk next to the function name, as opposed to the function keyword, such as function *generatorFunction(). This works the same, but function* is a more widely accepted syntax.

有时,您会在函数名称旁边看到星号,而不是像function *generatorFunction()这样的function关键字。 它的工作原理相同,但是function*是更广泛接受的语法。

Generator functions can also be defined in an expression, like regular functions:

生成器函数也可以在表达式中定义,例如常规函数

// Generator function expression
const generatorFunction = function* () {}

Generators can even be the methods of an object or class:

生成器甚至可以是对象的方法:

// Generator as the method of an object
const generatorObj = {
*generatorMethod() {},
}// Generator as the method of a class
class GeneratorClass {
*generatorMethod() {}
}

The examples throughout this article will use the generator function declaration syntax.

本文中的所有示例将使用生成器函数声明语法。

Note: Unlike regular functions, generators cannot be constructed with the new keyword, nor can they be used in conjunction with arrow functions.

注意 :与常规函数不同,生成器不能使用 new 关键字 构造 ,也不能与 箭头函数 结合使用

Now that you know how to declare generator functions, lets look at the iterable Generator objects that they return.

现在您知道如何声明生成器函数,让我们看一下它们返回的可迭代Generator对象。

生成器对象 (Generator Objects)

Traditionally, functions in JavaScript run to completion, and calling a function will return a value when it arrives at the return keyword. If the return keyword is omitted, a function will implicitly return undefined.

传统上,JavaScript中的函数会运行到完成状态,调用函数会在到达return关键字时返回一个值。 如果省略return关键字,则函数将隐式返回undefined

In the following code, for example, we declare a sum() function that returns a value that is the sum of two integer arguments:

例如,在下面的代码中,我们声明一个sum()函数,该函数返回一个值为两个整数参数之和的值:

// A regular function that sums two values
function sum(a, b) {
return a + b
}

Calling the function returns a value that is the sum of the arguments:

调用该函数将返回一个值,该值是参数的总和:

const value = sum(5, 6) // 11

A generator function, however, does not return a value immediately, and instead returns an iterable Generator object. In the following example, we declare a function and give it a single return value, like a standard function:

但是,生成器函数不会立即返回值,而是返回可迭代的Generator对象。 在下面的示例中,我们声明一个函数并给它一个返回值,就像标准函数一样:

// Declare a generator function with a single return value
function* generatorFunction() {
return 'Hello, Generator!'
}

When we invoke the generator function, it will return the Generator object, which we can assign to a variable:

当我们调用generator函数时,它将返回Generator对象,我们可以将其分配给变量:

// Assign the Generator object to generator
const generator = generatorFunction()

If this were a regular function, we would expect generator to give us the string returned in the function. However, what we actually get is an object in a suspended state. Calling generator will therefore give output similar to the following:

如果这是一个常规函数,则我们希望generator为我们提供函数中返回的字符串。 但是,我们实际上得到的是处于suspended状态的对象。 因此,调用generator将产生类似于以下内容的输出:

generatorFunction {<suspended>}
__proto__: Generator
[[GeneratorLocation]]: VM272:1
[[GeneratorStatus]]: "suspended"
[[GeneratorFunction]]: ƒ* generatorFunction()
[[GeneratorReceiver]]: Window
[[Scopes]]: Scopes[3]

The Generator object returned by the function is an iterator. An iterator is an object that has a next() method available, which is used for iterating through a sequence of values. The next() method returns an object with value and done properties. value represent the returned value, and done indicates whether the iterator has run through all its values or not.

该函数返回的Generator对象是一个迭代器 。 迭代器是一个具有next()方法可用的对象,该方法用于遍历一系列值。 next()方法返回具有valuedone属性的对象。 value表示返回的值, done表示迭代器是否已遍历其所有值。

Knowing this, let’s call next() on our generator and get the current value and state of the iterator:

知道这一点后,让我们在generator上调用next()并获取迭代器的当前值和状态:

// Call the next method on the Generator object
generator.next()

This will give the following output:

这将给出以下输出:

{value: "Hello, Generator!", done: true}

The value returned from calling next() is Hello, Generator!, and the state of done is true, because this value came from a return that closed out the iterator. Since the iterator is done, the generator function's status will change from suspended to closed. Calling generator again will give the following:

调用next()返回的值是Hello, Generator! 和状态donetrue ,因为这个数值从传来return是收出迭代器。 由于迭代器已完成,因此生成器功能的状态将从“ suspended变为“ closed 。 再次调用generator将给出以下信息:

generatorFunction {<closed>}

As of right now, we’ve only demonstrated how a generator function can be a more complex way to get the return value of a function. But generator functions also have unique features that distinguish them from normal functions. In the next section, we'll learn about the yield operator and see how a generator can pause and resume execution.

到目前为止,我们仅演示了生成器函数如何成为获取函数return值的更复杂方法。 但是生成器功能还具有独特的功能,可以将它们与正常功能区分开。 在下一节中,我们将了解yield运算符,并了解生成器如何暂停和恢复执行。

yield算子 (yield Operators)

Generators introduce a new keyword to JavaScript: yield. yield can pause a generator function and return the value that follows yield, providing a lightweight way to iterate through values.

生成器为JavaScript引入了一个新关键字: yieldyield可以暂停生成器函数并返回yield后面的值,从而提供了一种轻量级的方法来遍历值。

In this example, we’ll pause the generator function three times with different values, and return a value at the end. Then we will assign our Generator object to the generator variable.

在此示例中,我们将使用不同的值暂停生成器函数三次,然后在最后返回一个值。 然后,我们将Generator对象分配给generator变量。

// Create a generator function with multiple yields
function* generatorFunction() {
yield 'Neo'
yield 'Morpheus'
yield 'Trinity' return 'The Oracle'
}const generator = generatorFunction()

Now, when we call next() on the generator function, it will pause every time it encounters yield. done will be set to false after each yield, indicating that the generator has not finished. Once it encounters a return, or there are no more yields encountered in the function, done will flip to true, and the generator will be finished.

现在,当我们在generator函数上调用next()时,它将在每次遇到yield时暂停。 每个yield ,将done设置为false ,指示生成器尚未完成。 一旦遇到return ,或者函数中不再遇到yield ,则done将翻转为true ,并且生成器将完成。

Use the next() method four times in a row:

连续四次使用next()方法:

// Call next four times
generator.next()
generator.next()
generator.next()
generator.next()

These will give the following four lines of output in order:

这些将按顺序给出以下四行输出:

{value: "Neo", done: false}
{value: "Morpheus", done: false}
{value: "Trinity", done: false}
{value: "The Oracle", done: true}

Note that a generator does not require a return; if omitted, the last iteration will return {value: undefined, done: true}, as will any subsequent calls to next() after a generator has completed.

注意,生成器不需要return ; 如果省略,则最后一次迭代将返回{value: undefined, done: true} ,以及生成器完成后对next()任何后续调用。

遍历生成器 (Iterating Over a Generator)

Using the next() method, we manually iterated through the Generator object, receiving all the value and done properties of the full object. However, just like Array, Map, and Set, a Generator follows the iteration protocol, and can be iterated through with for...of:

使用next()方法,我们手动遍历Generator对象,接收完整对象的所有valuedone属性。 但是,就像ArrayMap SetGenerator遵循迭代协议 ,可以使用for...of进行迭代:

// Iterate over Generator object
for (const value of generator) {
console.log(value)
}

This will return the following:

这将返回以下内容:

Neo
Morpheus
Trinity

The spread operator can also be used to assign the values of a Generator to an array.

扩展运算符还可以用于将Generator的值分配给数组。

// Create an array from the values of a Generator object
const values = [...generator]console.log(values)

This will give the following array:

这将给出以下数组:

(3) ["Neo", "Morpheus", "Trinity"]

Both spread and for...of will not factor the return into the values (in this case, it would have been 'The Oracle').

传播和for...of都不会考虑return值的情况(在这种情况下,它将是'The Oracle' )。

Note: While both of these methods are effective for working with finite generators, if a generator is dealing with an infinite data stream, it won’t be possible to use spread or for...of directly without creating an infinite loop.

注意 :虽然这两种方法对于使用有限生成器都是有效的,但是如果生成器正在处理无限数据流,则 for...of 不创建无限循环的情况下 将无法直接使用spread或 for...of

关闭发电机 (Closing a Generator)

As we’ve seen, a generator can have its done property set to true and its status set to closed by iterating through all its values. There are two additional ways to immediately cancel a generator: with the return() method, and with the throw() method.

如我们所见,生成器可以通过迭代所有值将其done属性设置为true并将其状态设置为closed 。 有两种其他方法可以立即取消生成器:使用return()方法和throw()方法。

With return(), the generator can be terminated at any point, just as if a return statement had been in the function body. You can pass an argument into return(), or leave it blank for an undefined value.

使用return() ,可以在任何时候终止生成器,就像在函数体中使用return语句一样。 您可以将参数传递给return() ,也可以将其保留为空白以获取未定义的值。

To demonstrate return(), we'll create a generator with a few yield values but no return in the function definition:

为了演示return() ,我们将创建一个生成器,该生成器具有一些yield值,但函数定义中没有return

function* generatorFunction() {
yield 'Neo'
yield 'Morpheus'
yield 'Trinity'
}const generator = generatorFunction()

The first next() will give us 'Neo', with done set to false. If we invoke a return() method on the Generator object right after that, we'll now get the passed value and done set to true. Any additional call to next() will give the default completed generator response with an undefined value.

第一个next()将为我们提供'Neo' ,将done设置为false 。 如果我们调用return()的方法Generator之后客体的权利,我们现在会得到传递价值和done设置为true 。 对next()任何其他调用都将为默认的完整生成器响应提供一个未定义的值。

To demonstrate this, run the following three methods on generator:

为了证明这一点,请在generator上运行以下三种方法:

generator.next()
generator.return('There is no spoon!')
generator.next()

This will give the three following results:

这将给出以下三个结果:

{value: "Neo", done: false}
{value: "There is no spoon!", done: true}
{value: undefined, done: true}

The return() method forced the Generator object to complete and to ignore any other yield keywords. This is particularly useful in asynchronous programming when you need to make functions cancelable, such as interrupting a web request when a user wants to perform a different action, as it is not possible to directly cancel a Promise.

return()方法强制Generator对象完成操作,并忽略任何其他yield关键字。 当您需要取消功能时,这在异步编程中特别有用,例如当用户想要执行其他操作时中断Web请求,因为不可能直接取消Promise。

If the body of a generator function has a way to catch and deal with errors, you can use the throw() method to throw an error into the generator. This starts up the generator, throws the error in, and terminates the generator.

如果生成器函数的主体具有捕获和处理错误的方法,则可以使用throw()方法将错误抛出到生成器中。 这将启动生成器,引发错误,并终止生成器。

To demonstrate this, we will put a try...catch inside the generator function body and log an error if one is found:

为了证明这一点,我们将try...catch放在生成器函数体内,如果发现错误,则记录错误:

// Define a generator function
function* generatorFunction() {
try {
yield 'Neo'
yield 'Morpheus'
} catch (error) {
console.log(error)
}
}// Invoke the generator and throw an error
const generator = generatorFunction()

Now, we will run the next() method, followed by throw():

现在,我们将运行next()方法,然后运行throw()

generator.next()
generator.throw(new Error('Agent Smith!'))

This will give the following output:

这将给出以下输出:

{value: "Neo", done: false}
Error: Agent Smith!
{value: undefined, done: true}

Using throw(), we injected an error into the generator, which was caught by the try...catch and logged to the console.

使用throw() ,我们向生成器注入了一个错误,该错误被try...catch并记录到控制台。

生成器对象的方法和状态 (Generator Object Methods and States)

The following table shows a list of methods that can be used on Generator objects:

下表显示了可以在Generator对象上使用的方法的列表:

MethodDescriptionnext()Returns the next value in a generatorreturn()Returns a value in a generator and finishes the generatorthrow()Throws an error and finishes the generator

MethodDescription next()返回生成器中的下一个值return()返回生成器中的值并完成生成器throw()引发错误并完成生成器

The next table lists the possible states of a Generator object:

下表列出了Generator对象的可能状态:

StatusDescriptionsuspendedGenerator has halted execution but has not terminatedclosedGenerator has terminated by either encountering an error, returning, or iterating through all values

StatusDescription suspended Generator已停止执行,但尚未终止closed Generator通过遇到错误,返回或遍历所有值而终止

yield委托 (yield Delegation)

In addition to the regular yield operator, generators can also use the yield* expression to delegate further values to another generator. When the yield* is encountered within a generator, it will go inside the delegated generator and begin iterating through all the yields until that generator is closed. This can be used to separate different generator functions to semantically organize your code, while still having all their yields be iterable in the right order.

除了常规的yield运算符之外,生成器还可以使用yield*表达式将其他值委托给另一个生成器。 当在生成器中遇到yield*时,它将进入委托的生成器内部并开始遍历所有yield直到该生成器关闭。 这可以用于分离不同的生成功能,语义组织代码,同时还具有所有的yield S为迭代以正确的顺序。

To demonstrate, we can create two generator functions, one of which will yield* operate on the other:

为了演示,我们可以创建两个生成器函数,其中一个将对另一个函数yield*

// Generator function that will be delegated to
function* delegate() {
yield 3
yield 4
}// Outer generator function
function* begin() {
yield 1
yield 2
yield* delegate()
}

Next, let’s iterate through the begin() generator function:

接下来,让我们遍历begin()生成器函数:

// Iterate through the outer generator
const generator = begin()for (const value of generator) {
console.log(value)
}

This will give the following values in the order they are generated:

这将按生成顺序给出以下值:

1
2
3
4

The outer generator yielded the values 1 and 2, then delegated to the other generator with yield*, which returned 3 and 4.

外部生成器产生值12 ,然后将其委托给另一个带有yield*生成器,返回34

yield* can also delegate to any object that is iterable, such as an Array or a Map. Yield delegation can be helpful in organizing code, since any function within a generator that wanted to use yield would also have to be a generator.

yield*还可以委托给任何可迭代的对象,例如Array或Map。 产量委托对于组织代码很有帮助,因为要使用yield的生成器中的任何函数也必须是生成器。

无限数据流 (Infinite Data Streams)

One of the useful aspects of generators is the ability to work with infinite data streams and collections. This can be demonstrated by creating an infinite loop inside a generator function that increments a number by one.

生成器的有用方面之一是能够处理无限数据流和集合。 这可以通过在生成器函数内创建一个无限循环来证明,该循环将数字加一。

In the following code block, we define this generator function and then initiate the generator:

在下面的代码块中,我们定义此生成器函数,然后启动生成器:

// Define a generator function that increments by one
function* incrementer() {
let i = 0 while (true) {
yield i++
}
}// Initiate the generator
const counter = incrementer()

Now, iterate through the values using next():

现在,使用next()遍历值:

// Iterate through the values
counter.next()
counter.next()
counter.next()
counter.next()

This will give the following output:

这将给出以下输出:

{value: 0, done: false}
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}

The function returns successive values in the infinite loop while the done property remains false, ensuring that it will not finish.

该函数将在infinite循环中返回连续的值,而done属性仍为false ,以确保它不会完成。

With generators, you don’t have to worry about creating an infinite loop, because you can halt and resume execution at will. However, you still have to have caution with how you invoke the generator. If you use spread or for...of on an infinite data stream, you will still be iterating over an infinite loop all at once, which will cause the environment to crash.

使用生成器,您不必担心创建无限循环,因为您可以随意停止并恢复执行。 但是,您仍然必须谨慎对待如何调用生成器。 如果在无限数据流上使用spread或for...of ,则仍将一次遍历无限循环,这将导致环境崩溃。

For a more complex example of an infinite data stream, we can create a Fibonacci generator function. The Fibonacci sequence, which continuously adds the two previous values together, can be written using an infinite loop within a generator as follows:

对于无限数据流的更复杂的示例,我们可以创建一个Fibonacci生成器函数。 斐波那契数列将两个先前的值连续加在一起,可以使用生成器中的无限循环来编写,如下所示:

// Create a fibonacci generator function
function* fibonacci() {
let prev = 0
let next = 1 yield prev
yield next // Add previous and next values and yield them forever
while (true) {
const newVal = next + prev yield newVal prev = next
next = newVal
}
}

To test this out, we can loop through a finite number and print the Fibonacci sequence to the console.

为了测试这一点,我们可以遍历一个有限的数并将Fibonacci序列打印到控制台。

// Print the first 10 values of fibonacci
const fib = fibonacci()for (let i = 0; i < 10; i++) {
console.log(fib.next().value)
}

This will give the following:

这将给出以下内容:

0
1
1
2
3
5
8
13
21
34

The ability to work with infinite data sets is one part of what makes generators so powerful. This can be useful for examples like implementing infinite scroll on the frontend of a web application, or operating on sound wave data.

处理无限数据集的能力是使生成器如此强大的原因之一。 这对于例如在Web应用程序的前端上实现无限滚动或对声波数据进行操作的示例很有用。

在生成器中传递值 (Passing Values in Generators)

Throughout this article, we’ve used generators as iterators, and we’ve yielded values in each iteration. In addition to producing values, generators can also consume values from next(). In this case, yield will contain a value.

在整个本文中,我们将生成器用作迭代器,并且在每次迭代中都产生了值。 除了产生值之外,生成器还可以使用next()值。 在这种情况下, yield将包含一个值。

It’s important to note that the first next() that is called will not pass a value, but will only start the generator. To demonstrate this, we can log the value of yield and call next() a few times with some values.

重要的是要注意,第一个next()不会传递值,而只会启动生成器。 为了证明这一点,我们可以记录yield的值,并使用某些值多次调用next()

function* generatorFunction() {
console.log(yield)
console.log(yield) return 'The end'
}const generator = generatorFunction()generator.next()
generator.next(100)
generator.next(200)

This will give the following output:

这将给出以下输出:

100
200
{value: "The end", done: true}

It is also possible to seed the generator with an initial value. In the following example, we’ll make a for loop and pass each value into the next() method, but pass an argument to the inital function as well:

也可以使用初始值为生成器提供种子。 在下面的示例中,我们将进行一个for循环,并将每个值传递给next()方法,但还将一个参数传递给inital函数:

function* generatorFunction(value) {
while (true) {
value = yield value * 10
}
}// Initiate a generator and seed it with an initial value
const generator = generatorFunction(0)for (let i = 0; i < 5; i++) {
console.log(generator.next(i).value)
}

We’ll retrieve the value from next() and yield a new value to the next iteration, which is the previous value times ten. This will give the following:

我们将从next()检索值,并为下一次迭代生成一个新值,该值是前一个值乘以10。 这将给出以下内容:

0
10
20
30
40

Another way to deal with starting up a generator is to wrap the generator in a function that will always call next() once before doing anything else.

处理生成器的另一种方法是将生成器包装在一个函数中,该函数将在执行其他任何操作之前始终调用next()一次。

与发电机async / await (async/await with Generators)

An asynchronous function is a type of function available in ES6+ JavaScript that makes working with asynchronous data simpler and easier to understand by making it appear synchronous. Generators have a more extensive array of capabilities than asynchronous functions, but are capable of replicating similar behavior. Implementing asynchronous programming in this way can increase the flexibility of your code.

异步函数是ES6 + JavaScript中提供的一种函数,通过使异步数据看起来像同步的,它使处理异步数据更加简单和容易理解。 生成器比异步函数具有更多的功能,但是能够复制相似的行为。 以这种方式实现异步编程可以提高代码的灵活性。

In this section, we will demonstrate an example of reproducing async/await with generators.

在本节中,我们将演示一个使用生成器再现async / await的示例。

Let’s build an asynchronous function that uses the Fetch API to get data from the JSONPlaceholder API (which provides example JSON data for testing purposes) and logs the response to the console.

让我们构建一个异步函数, 函数使用Fetch APIJSONPlaceholder API获取数据(该API提供示例JSON数据用于测试)并将响应记录到控制台。

Start out by defining an asynchronous function called getUsers that fetches data from the API and returns an array of objects, then call getUsers:

首先定义一个名为getUsers的异步函数,该函数从API提取数据并返回对象数组,然后调用getUsers

const getUsers = async function () {
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const json = await response.json() return json
}// Call the getUsers function and log the response
getUsers().then((response) => console.log(response))

This will give the following JSON data:

这将提供以下JSON数据:

[ {id: 1, name: "Leanne Graham" ...},
{id: 2, name: "Ervin Howell" ...},
{id: 3, name": "Clementine Bauch" ...},
{id: 4, name: "Patricia Lebsack"...},
{id: 5, name: "Chelsey Dietrich"...},
{id: 6, name: "Mrs. Dennis Schulist"...},
{id: 7, name: "Kurtis Weissnat"...},
{id: 8, name: "Nicholas Runolfsdottir V"...},
{id: 9, name: "Glenna Reichert"...},
{id: 10, name: "Clementina DuBuque"...}]

Using generators, we can create something almost identical that does not use the async/await keywords. Instead, it will use a new function we create, and yield values instead of await promises.

使用生成器,我们可以创建几乎不使用async / await关键字的相同内容。 取而代之的是,它将使用我们创建的新函数,并yield值而不是await诺言。

In the following code block, we define a function called getUsers that uses our new asyncAlt function (which we will write later on) to mimic async/await.

在下面的代码块中,我们定义了一个名为getUsers的函数,该函数使用新的asyncAlt函数(稍后将进行编写)来模仿async / await

const getUsers = asyncAlt(function* () {
const response = yield fetch('https://jsonplaceholder.typicode.com/users')
const json = yield response.json() return json
})// Invoking the function
getUsers().then((response) => console.log(response))

As we can see, it looks almost identical to the async/await implementation, except that there is a generator function being passed in that yields values.

如我们所见,它看起来与async / await实现几乎相同,除了其中传递了生成值的生成器函数外。

Now we can create an asyncAlt function that resembles an asynchronous function. asyncAlt has a generator function as a parameter, which is our function that yields the promises that fetch returns. asyncAlt returns a function itself, and resolves every promise it finds until the last one:

现在我们可以创建类似于异步函数的asyncAlt函数。 asyncAlt具有一个生成器函数作为参数,这是我们的函数,可产生fetch返回的承诺。 asyncAlt本身asyncAlt返回一个函数,并解决找到的每个诺言,直到最后一个:

// Define a function named asyncAlt that takes a generator function as an argument
function asyncAlt(generatorFunction) {
// Return a function
return function () {
// Create and assign the generator object
const generator = generatorFunction() // Define a function that accepts the next iteration of the generator
function resolve(next) {
// If the generator is closed and there are no more values to yield,
// resolve the last value
if (next.done) {
return Promise.resolve(next.value)
} // If there are still values to yield, they are promises and
// must be resolved.
return Promise.resolve(next.value).then((response) => {
return resolve(generator.next(response))
})
} // Begin resolving promises
return resolve(generator.next())
}
}

This will give the same output as the async/await version:

这将提供与async / await版本相同的输出:

[ {id: 1, name: "Leanne Graham" ...},
{id: 2, name: "Ervin Howell" ...},
{id: 3, name": "Clementine Bauch" ...},
{id: 4, name: "Patricia Lebsack"...},
{id: 5, name: "Chelsey Dietrich"...},
{id: 6, name: "Mrs. Dennis Schulist"...},
{id: 7, name: "Kurtis Weissnat"...},
{id: 8, name: "Nicholas Runolfsdottir V"...},
{id: 9, name: "Glenna Reichert"...},
{id: 10, name: "Clementina DuBuque"...}]

Note that this implementation is for demonstrating how generators can be used in place of async/await, and is not a production-ready design. It does not have error handling set up, nor does it have the ability to pass parameters into the yielded values. Though this method can add flexibility to your code, often async/await will be a better choice, since it abstracts implementation details away and lets you focus on writing productive code.

请注意,此实现用于演示如何使用生成器代替async / await ,而不是可用于生产的设计。 它没有设置错误处理,也没有能力将参数传递给产生的值。 尽管此方法可以为您的代码增加灵活性,但通常async/await将是一个更好的选择,因为它抽象了实现细节,使您专注于编写高效的代码。

结论 (Conclusion)

Generators are processes that can halt and resume execution. They are a powerful, versatile feature of JavaScript, although they are not commonly used. In this tutorial, we learned about generator functions and generator objects, methods available to generators, the yield and yield* operators, and using generators with finite and infinite data sets. We also explored one way to implement asynchronous code without nested callbacks or long promise chains

生成器是可以暂停并恢复执行的进程。 它们是JavaScript的强大功能,尽管并不常用。 在本教程中,我们了解了生成器函数和生成器对象,生成器可用的方法, yieldyield*运算符,以及如何使用具有有限和无限数据集的生成器。 我们还探索了一种无需嵌套回调或长承诺链即可实现异步代码的方法

翻译自: https://medium.com/swlh/understanding-generators-in-javascript-esma-script-fcca9eda19fa

esma标准

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值