-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path3-generators.js
109 lines (97 loc) · 3.04 KB
/
3-generators.js
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
103
104
105
106
107
108
109
const randomNumber = require('random-number')
/*
Generators were introduced in ES6 (ECMAScript 2015) alongside Iterators and Promises.
These examples assume general knowledge of Iterators in JavaScript.
Generators are essentially syntactic sugar for custom iterators.
They allow pausing the execution of functions (using yield).
*/
// Helper functions
const makeCat = () => {
const catSizes = ['huge', 'grande', 'tiny'];
const catHobbies = ['napping', 'eating', 'sleeping', 'dancing', 'snoring'];
return randomItem(catSizes) + ' ' +
randomItem(catHobbies) + ' ' +
'cat'
}
// source: https://github.com/mpj/funfuniterators/blob/master/random-item.js
function randomItem(array) {
const randomIndex = randomNumber({
min: 0,
max: array.length - 1,
integer: true
})
return array[randomIndex]
}
/* Generator example */
(() => {
console.log('Generator example')
const catArmy = {
[Symbol.iterator]: function*() {
while(true){
const enoughCats = Math.random() > 0.75
if (enoughCats) return
yield makeCat()
}
}
}
// the Iterator method would have involved implementing a next method
/*[Symbol.iterator]: () => {
return {
next: () => {
const enoughcats = Math.random() > 0.75
if (!enoughCats)
return {
value: makeCat(),
done: false
}
return { done: true }
}
}
}*/
for (const cat of catArmy) {
console.log(cat);
}
})()
;(() => {
console.log('Example with the underlying iterator')
function* someCats(){
while(true){
const enoughCats = Math.random() > 0.75
if (enoughCats) return
yield makeCat()
}
}
const iterator = someCats()
console.log('iterator.next(): ', iterator.next())
})()
/*
When we call iterator.next(), the generator executes until it reaches
a yield, and then it pauses and whatever was yielded is returned as
the value of the next call to iterator.next()
*/
;(() => {
console.log('Example with only yield')
function* someCats(){
yield 'sammy the siamese'
yield 'fluffy the ragdoll'
yield 'ginger the tabbycat'
}
const iterator = someCats()
console.log('iterator.next(): ', iterator.next()) //'sammy the siamese'
console.log('iterator.next(): ', iterator.next()) //'fluffy the ragdoll'
console.log('iterator.next(): ', iterator.next()) //'ginger the tabbycat'
})()
const URL = 'https://cataas.com/cat?json=true';
/*
Generator functions can be used asynchronously
*/
(async () => {
console.log('Example with async generator')
async function* someCats(){
const catData = await fetch(URL)
yield { photo: catData.url, name: makeCat()}
}
const iterator = someCats()
iterator.next() //a pending promise
.then((data) => console.log(data)) //returns an object {value: obj returned by yield, done: boolean (will be false)}
})()