——技术凝聚实力 专业创新出版

# 1由来

const fibonacci = [ 0,1 ]
const n =10

for (let i =2; i < n -1;++i) {
fibonacci.push(fibonacci[i -1] + fibonacci[i -2])
}
console.log(fibonacci) //=> [0, 1, 1, 2, 3, 5, 8, 13, 21]

function*fibo() {
let a =0
let b =1

yield a
yield b

while (true) {
let next = a + b
a = b
b = next
yield next
}
}

let generator =fibo()

for (var i =0; i <10; i++)
console.log(generator.next().value) //=> 0 1 1 2 3 5 8 13 21 34 55

# 2基本概念

## 2.1 生成器函数（Generator Function）

function*fibo() {
// ...
}

const fnName =function*() {/* ... */}

## 2.2 生成器（Generator）

const inputValue =yield outputValue

# 3使用方法

## 3.1 构建生成器函数

function*genFn() {
let a =2

yield a

while (true) {
yield a = a / (2* a +1)
}
}

## 3.2启动生成器

const gen =genFn()

class Generator {
next(value)
throw(error)
[@@iterator]()
}

{
value: Any,
done: Boolean
}

## 3.3 运行生成器内容

for (const a of gen) {
if (a <1/100) break

console.log(a)
}
//=>
//  2
//  0.4
//  0.2222222222
//  ...

# 4深入理解

## 4.2 生成器函数以及生成器对象的检测

functionPoint(x, y) {
if (!(thisinstanceof Point)) returnnewPoint(x, y)
// ...
}

const p1 =newPoint(1,2)
const p2 =Point(2,3)

String()  //=> ""
Number()  //=> 0
Boolean() //=> false
Object()  //=> Object {}
Array()   //=> []
Date()    //=> the current time
RegExp()  //=> /(?:)/

function*genFn() {}
const gen =genFn()

console.log(genFn.constructor.prototype) //=> GeneratorFunction
console.log(gen.constructor.prototype)   //=> Generator

console.log(gen instanceof genFn) //=> true

functionisGeneratorFunction(fn) {
const genFn = (function*(){}).constructor

return fn instanceof genFn
}

function*genFn() {
let a =2

yield a

while (true) {
yield a = a / (2* a +1)
}
}

console.log(isGeneratorFunction(genFn)) //=> true

functionisGenerator(obj) {
returnobj.toString?obj.toString() ==='[object Generator]' : false
}

function*genFn() {}
const gen =genFn()

console.log(isGenerator(gen)) //=> true
console.log(isGenerator({}))  //=> false

functionisGenerator(obj) {
if (Symbol &&Symbol.toStringTag) {
return obj[Symbol.toStringTag] ==='Generator'
}elseif (obj.toString) {
returnobj.toString() ==='[object Generator]'
}

returnfalse
}

console.log(isGenerator(gen)) //=> true
console.log(isGenerator({}))  //=> false

function*genFn() {}

console.log(genFn[Symbol.toStringTag]) //=> GeneratorFunction

functionisGeneratorFunction(fn) {
return fn[Symbol &&Symbol.toStringTag?Symbol.toStringTag : false] ==='GeneratorFunction'
}

console.log(isGeneratorFunction(genFn)) //=> true

functionisGeneratorFunction(fn) {
// If the current engine supports Symbol and @@toStringTag
if (Symbol &&Symbol.toStringTag) {
return fn[Symbol.toStringTag] ==='GeneratorFunction'
}

// Using instanceof statement for detecting
const genFn = (function*(){}).constructor

return fn instanceof genFn
}

console.log(isGeneratorFunction(genFn)) //=> true

## 4.3 生成器嵌套

// Newton-Cotes formulas
function*newton_cotes(f, a, b, n) {
const gaps = (b - a) / n
const h = gaps / 2

for (var i =0; i < n; i++) {
yield h / 45*
(7*f(a + i * gaps) +
32*f(a + i * gaps +0.25* gaps) +
12*f(a + i * gaps +0.5* gaps) +
32*f(a + i * gaps +0.75* gaps) +
7*f(a + (i +1) * gaps))
}
}

function*foo() {
yield1
yield2
}

function*bar() {
yield*foo()
yield3
yield4
}

for (const n of bar()) console.log(n)
//=>
//  1
//  2
//  3
//  4

function*Part1(n) {
yield*newton_cotes(x =>Math.pow(x,2),-2,0, n)
}

function*Part2(n) {
yield*newton_cotes(x =>Math.sin(x),0,2, n)
}

function*sum() {
const n =100

yield*Part1(n)
yield*Part2(n)
}

## 4.4生成器与协程

io1((err, res1) =>{
io2(res1, (err, res2) =>{
io3(res2, (err, res3) =>{
io4(res3, (err, res4) =>{
io5(res5, (err, res5) =>{
// ......
})
})
})
})
})

// Before
functionecho(content, callback) {
callback(null, content)
}

// After
functionecho(content) {
return callback =>{
callback(null, content)
}
}

functionrun(genFn) {
const gen =genFn()

const next = value =>{
const ret =gen.next(value)
if (ret.done) return

ret.value((err, val) =>{
if (err) returnconsole.error(err)

// Loop
next(val)
})
}

// First call
next()
}

run(function*() {
const msg1 =yieldecho('Hello')
const msg2 =yieldecho(\${msg1} World)

console.log(msg2) //=> Hello Wolrd
})

import co from'co'
import{ promisify }from'bluebird'
import fs from'fs'
import path from'path'

const filepath =path.resolve(process.cwd(),'./data.txt')
const defaultData =newBuffer('Hello World')

co(function*() {
const exists =yieldpromisify(fs.exists)(filepath)

if (exists) {
// ...
}else{
yieldpromisify(fs.writeFile)(filepath, defaultData)
// ...
}
})

#### elasticsearch详解(一)——es是什么、能做什么？

2017-11-16 14:35:28

#### es构成

2017-08-15 16:49:47

#### Elasticsearch 中如何巧妙地使用聚合函数达到数据库中having的效果

2018-02-01 15:09:55

#### ES —（函数扩展）

2017-08-16 14:11:31

#### es的查询

2017-05-22 23:38:40

#### es 基本语法 使用 案例

2017-03-16 12:36:09

#### ES6/ES2015—常用介绍

2018-01-23 15:27:10

#### ElasticSearch学习总结（二）：ES介绍与架构说明

2018-02-28 18:18:07

#### Python源码分析5 – 语法分析器PyParser

2013-12-08 23:53:07

#### ES6部分方法点评（三）：babel-preset-es2015-loose可转换且移动端兼容性较好的语法

2016-10-27 09:40:29