了解JavaScript生成器(译文)
By S.F.
本文链接 https://www.kyfws.com/news/understanding-javascript-generators/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 8 分钟阅读 - 3770 个词 阅读量 0了解JavaScript生成器(译文)
原文地址:https://www.codeproject.com/Articles/5279077/Understanding-JavaScript-Generators
译文由本站翻译
前言
JavaScript generators and how it differs from iterators JavaScript生成器及其与迭代器的区别 In this article, we will take a look at JavaScript generators and how it is different from iterators. Moreover, we will go in-depth with its methods and see some tips when using function generators on an arrow function and inside an object. 在本文中,我们将介绍JavaScript生成器以及它与迭代器的不同之处.此外,我们将深入研究其方法,并在箭头函数和对象内部使用函数生成器时看到一些提示.
(Introduction) 介绍
(If you have been grasping or are done grasping JavaScript iterators and searching JavaScript generators, you are at the right place. In this article, we will take a look at JavaScript generators and how they are different from iterators. Moreover, we will go in-depth with its methods and see some tips when using function generators on an arrow function and inside an object.) 如果您已经掌握或已经掌握JavaScript迭代器并搜索JavaScript生成器,那么您来对地方了.在本文中,我们将介绍JavaScript生成器以及它们与迭代器的不同之处.此外,我们将深入研究其方法,并在箭头函数和对象内部使用函数生成器时看到一些提示.
(Background) 背景
(It’s good to suggest to have a basic understanding of iterators, one reason is to recognize the differences between iterators and generators. In such a case, you can read) 建议最好对迭代器有一个基本的了解,原因之一是要认识到迭代器和生成器之间的差异.在这种情况下,您可以阅读 (here) 这里 (or you can Google search. However; if this doesn’t apply to you, you can skip the reading part and proceed to the next section.) 或者您可以Google搜索.然而;如果这不适用于您,则可以跳过阅读部分,然后继续进行下一部分.
(What is a JavaScript Generator?) 什么是JavaScript生成器?
(Great! You have probably read the recommended reading material above before jumping into this section. And, hopefully, that helped and I want to say: “Thank you”. OK, then let’s get started.) 大!在跳到本节之前,您可能已经阅读了上面推荐的阅读材料.希望能有所帮助,我想说:“谢谢”.好的,让我们开始吧. (In my opinion, JavaScript custom iterators are useful when utilized but it demands careful and thorough programming because of its internal state. Thereby, we have an alternative, JavaScript generator, to allow us (JavaScript programmers) to define a single function whose execution is continuous.) 在我看来,JavaScript自定义迭代器在使用时很有用,但由于其内部状态,需要仔细而彻底的编程.因此,我们有了另一种JavaScript生成器,以允许我们(JavaScript程序员)定义一个连续执行的函数.
(Things to Remember about JavaScript Generators) 关于JavaScript生成器的注意事项
-
(It appears to be a normal function, but behaves like an iterator.) 它似乎是一个正常函数,但其行为类似于迭代器.
-
(It is written using the) 它是使用
function*
(syntax.) 句法. -
(Invoking a generator function doesn’t execute its body immediately, but rather returns a new instance of the generator object () 调用生成器函数不会立即执行其主体,而是返回生成器对象的新实例((an object that implements both, iterable and iterator protocols) 同时实现可迭代和迭代器协议的对象().) ).
-
(It is a function that returns multiple values one by one.) 它是一个函数,它一个接一个地返回多个值.
-
(It can be paused and resumed. This is possible through the usage of the) 可以暂停和继续.这可以通过使用
yield
(keyword.) 关键词.
(Let’s see an example below:) 让我们看下面的例子:
/**
* It is written using the function* syntax. [✓]
* Appears to be a normal function. [✓]
* Uses the yield keyword. [✓]
*/
function* myFavoriteFruits() {
let grapeFruit = yield "Grapefruit",
pineApple = yield "Pineapple",
apple = yield "Apples",
mango = yield "Mango";
}
(Now, that we have seen how to declare a generator, why not invoke the function generator? Finally, check and see the returned object.) 现在,我们已经看到了如何声明生成器,为什么不调用函数生成器呢?最后,检查并查看返回的对象. (Let’s see an example below:) 让我们看下面的例子:
/**
* Invoking a generator function doesn't execute its body immediately.
*/
var mygenerator = myFavoriteFruits();
//Output: Returns a new instance of the generator object.
console.log(mygenerator);
(Output) 输出量
(As you can see, the) 如您所见, myFavoriteFruits
((generator function) returns an instance of the generator) (生成器函数)返回生成器的实例 object
(. Moreover, this) .而且这个 object
(implements both iterable and iterator protocols.) 实现可迭代协议和迭代器协议.
(JavaScript Generator Instance Methods) JavaScript Generator实例方法
(The JavaScript generator has three instance methods:) JavaScript生成器具有三个实例方法:
-
next()
-
return()
-
throw()
(The next() Method) next()方法
(When the) 当…的时候 next()
(method of the generator object executes, it looks for the function’s body until the) 生成器对象的方法执行后,它会寻找函数的主体,直到 yield
(keyword is encountered. Thereby, it returns the yielded value and pauses the function. Again, when the) 遇到关键字.因此,它返回产生的值并暂停该功能.同样,当 next()
(method is invoked, it resumes the execution, and then returns the next yielded value.) 方法被调用,它将继续执行,然后返回下一个产生的值.
(Lastly, the method) 最后,方法 next()
(has two properties:) 有两个属性: value
(and) 和 done
(.) .
-
value
(property is the returned value by the iterator.) property是迭代器返回的值. -
done
(property is) 财产是true
(when the generator function doesn’t) 当生成器功能不起作用时yield
(any more value.) 任何更多的价值.
(Let’s see an example below:) 让我们看下面的例子:
function* myFavoriteFruits() {
let grapeFruit = yield "Grapefruit",
pineApple = yield "Pineapple",
apple = yield "Apples",
mango = yield "Mango";
//output:undefined undefined undefined undefined -> more of this later.
console.log(grapeFruit, pineApple, apple, mango);
}
var mygenerator = myFavoriteFruits();
//output: {value: "Grapefruit", done: false}
console.log(mygenerator.next());
//output: {value: "Pineapple", done: false}
console.log(mygenerator.next());
//output: {value: "Apples", done: false}
console.log(mygenerator.next());
//output: {value: "Mango", done: false}
console.log(mygenerator.next());
//output: {value: undefined, done: true}
console.log(mygenerator.next());
(Another thing to remember on the) 要记住的另一件事 next()
(method. We can pass an optional argument to it. This argument becomes the value returned by the) 方法.我们可以给它传递一个可选参数.此参数成为 yield
(statement, where the generator function is currently paused.) 语句,生成器功能当前已暂停的位置.
(To go back to the previous example, on line 9, we have this statement:) 回到第9行的上一个示例,我们有以下语句: console.log(grapeFruit, pineApple, apple, mango);
(which resulted in) 导致 undefined undefined undefined undefined
(. To fix this, let’s see an example below:) .要解决此问题,请看下面的示例:
function* myFavoriteFruits() {
let grapeFruit = yield "Grapefruit",
pineApple = yield "Pineapple",
apple = yield "Apples",
mango = yield "Mango";
//output:Grapefruit Pineapple Apples Mango
console.log(grapeFruit, pineApple, apple, mango);
}
var mygenerator2 = myFavoriteFruits();
//output: {value: "Grapefruit", done: false}
console.log(mygenerator2.next());
//output: {value: "Pineapple", done: false}
console.log(mygenerator2.next("Grapefruit"));
//output: {value: "Apples", done: false}
console.log(mygenerator2.next("Pineapple"));
//output: {value: "Mango", done: false}
console.log(mygenerator2.next("Apples"));
//output: {value: undefined, done: true}
console.log(mygenerator2.next("Mango"));
(The return() Method) return()方法
(The) 的 return()
(method can end the generator function before it can yield all the values. Moreover, this method takes an optional argument and acts as the final value to return.) 方法可以在生成所有值之前结束生成器函数.此外,此方法采用可选参数,并作为要返回的最终值.
function* beKindToPeople() {
yield "Be mindful";
yield "Don't discriminate";
yield "Buy someone a coffee";
}
var myKindnessActGenerator = beKindToPeople();
//output: Be mindful
console.log(myKindnessActGenerator.next().value);
//output: Don't discriminate
console.log(myKindnessActGenerator.next().value);
//output: {value: "Consider kindness before you speak", done: true}
console.log(myKindnessActGenerator.return("Consider kindness before you speak"));
//output: true
console.log(myKindnessActGenerator.next().done);
(The throw() Method) throw()方法
(This method accepts the exception to be thrown. Thereby, you can manually trigger an exception inside the generator function.) 此方法接受要引发的异常.因此,您可以在生成器函数内部手动触发异常. (Let us see an example below:) 让我们看下面的例子:
function* howToBeHappy() {
try {
yield "Treat yourself like a friend";
} catch (error) {
console.log("Always be happy 1st try");
}
try {
yield "Challenge your negative thoughts";
} catch (error) {
console.log("Always be happy 2nd try");
}
try {
yield "Choose your friends wisely";
} catch (error) {
console.log("Always be happy 3rd try");
}
}
var myHappyGenerator = howToBeHappy();
//output: Treat yourself like a friend
console.log(myHappyGenerator.next().value);
/**
* output: Always be happy 1st try
* Challenge your negative thoughts
*/
console.log(myHappyGenerator.throw("Exception thrown but still be happy").value);
/**
* output: Always be happy 2nd try
* Choose your friends wisely
*/
console.log(myHappyGenerator.throw("Exception thrown but still be happy").value);
/**
* output:Always be happy 3rd try
* true
*/
console.log(myHappyGenerator.throw("Exception thrown but still be happy").done);
(The “yield” Keyword Inside the Function Generator*) 函数生成器中的" yield *“关键字
(This expression is used to delegate to another generator or iterable object. Hence, it iterates it to yield its values.) 该表达式用于委托给另一个生成器或可迭代对象.因此,对其进行迭代以产生其值. (Let’s see an example below:) 让我们看下面的例子:
function* respectSubordinates() {
yield "Know their strengths and weaknesses";
yield "Respectful to others."
}
function* showLove() {
yield "Listen";
yield* ['acts of service', 'encourage people', 'quality time'];
yield* respectSubordinates();
}
var loveIterator = showLove();
for (const value of loveIterator) {
console.log(value);
}
(Output) 输出量
(Generator as Methods Inside an Object) 生成器作为对象内部的方法
(Because JavaScript generator is a function too, you can add them to objects, too.) 因为JavaScript generator也是一个函数,所以您也可以将它们添加到对象中. (Let’s see some examples below.) 让我们在下面看一些例子.
-
(Object literal with function expression:) 具有函数表达式的对象文字:
-
(Object literal using method shorthand by prepending the method name with an asterisk ():) 使用方法速记的对象文字,方法名称前带有星号():
(These examples are equivalent to the previous examples; they just use a different syntax.) 这些示例与前面的示例等效;他们只是使用不同的语法.
(Why I Can’t Use An Arrow Function with JavaScript Generators?) 为什么我不能在JavaScript生成器中使用箭头功能?
(Based on my research, it is because of the) 根据我的研究,是因为 yield
(keyword. Please see the statement below from the) 关键词.请参阅下面的声明 (MDN) MDN (documentation:) 说明文件:
(“The yield keyword may not be used in an arrow function’s body unless it is further nested within it. Therefore, arrow functions cannot be used as generators.”) " yield关键字除非进一步嵌套在其中,否则不能在箭头函数的主体中使用.因此,箭头函数不能用作生成器."
(Here are the things I experimented with arrow functions that failed.) 这是我尝试失败的箭头功能的事情.
(Arrow function and using the) 箭头功能并使用 yield
(keyword. This one failed.) 关键词.这个失败了.
(Arrow function and using the “) 箭头功能,并使用” yield*
(” keyword. This one failed too.) “关键字.这个也失败了.
(Arrow function and use the asterisk to act as a generator and removed the) 箭头功能,并使用星号充当生成器,并删除了 yield
(keyword. Again, this one failed.) 关键词.再次,这一失败.
(Perhaps, the simple experiment is significant. However, come to think of it, I felt that using a generator in an arrow function appears vague.) 也许,简单的实验是有意义的.但是,考虑一下,我觉得在箭头函数中使用生成器似乎很模糊.
(Here is one of the things I observed with the arrow-function that was successful.) 这是我使用箭头功能观察到的成功之一.
(Before going to the sample code. Let us go back to the documentation. It says: “Unless it is further nested within it.” Let’s give it a try.) 在转到示例代码之前.让我们回到文档.它说:“除非它进一步嵌套在其中.“试一试吧. (Let us see a code sample below:) 让我们看下面的代码示例:
/**
* Arrow function that returns an object that has a function-generator.
*/
const mySampGenerator = () => ({
*beKindToPeopleIterator(items) {
for (let index = 0; index < items.length; index++) {
yield items[index];
}
}
});
/**
* Let's try if the function-generator works inside the arrow-function.
*/
let mySampIterator = mySampGenerator()
.beKindToPeopleIterator(
["Don't discriminate",
"Buy someone a coffee",
"Consider kindness before you speak"]);
console.log(mySampIterator);
(Output) 输出量
(Difference between Generators and Iterators) 生成器和迭代器之间的区别
(At last, this is our last section of this article. Based on research and observation, we can conclude that an iterator traverses a collection one at a time while a generator generates a sequence, one item at a time.) 最后,这是本文的最后一部分.根据研究和观察,我们可以得出结论,迭代器一次遍历一个集合,而生成器一次生成一个序列,一次一次.
(Summary) 概要
(In this post, we have tackled the concepts of JavaScript generators. We have started by looking at what a JavaScript generator is, go in-depth with its instance methods. Moreover, we have seen why we can’t use an arrow function directly, and some tips concerning generator function inside an object. Lastly, we have seen the difference between an iterator and a generator.) 在本文中,我们讨论了JavaScript生成器的概念.我们首先看一下什么是JavaScript生成器,并深入研究其实例方法.此外,我们已经了解了为什么不能直接使用箭头功能,以及有关对象内部生成器功能的一些技巧.最后,我们已经看到了迭代器和生成器之间的区别. (I hope you have enjoyed this article, as I have enjoyed writing it. Stay tuned for more. If you feel that you have something to say, please leave a comment below. Many thanks, until next time, happy programming!) 希望您喜欢我喜欢写这篇文章.敬请期待更多.如果您有话要说,请在下面发表评论.非常感谢,直到下一次,祝您编程愉快!
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
Javascript 新闻 翻译