(精华)2020年7月5日 JavaScript高级篇 ES6(generator)

举报
愚公搬代码 发表于 2021/10/19 00:52:45 2021/10/19
【摘要】 generator函数 介绍 es6提出的一种异步解决的方案执行这个generator函数会返回一个遍历器对象形式上区别之一 function关键字与函数名之间有一个*号形式上区别之二 函数内部使用yi...

generator函数 介绍

  • es6提出的一种异步解决的方案
  • 执行这个generator函数会返回一个遍历器对象
  • 形式上区别之一 function关键字与函数名之间有一个*号
  • 形式上区别之二 函数内部使用yield表达式

用法

function* helloGenerator(){
    yield 'hello'
    yield 'world'
    return 123
}

let res = helloGenerator()
// console.log(res);
console.log(res.next());
console.log(res.next());
console.log(res.next());
console.log(res.next());
console.log(res.next());
console.log(res.next());

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

与iterator接口的关系

let myIterator = {}
myIterator[Symbol.iterator] = function*(){
    yield 1;
    yield 2;
    yield 3;
    yield 4;
}
console.log([...myIterator]);

// generator函数执行返回一个迭代器对象 这一个对象本身也有Symbol.iterator属性
//  也是可以执行的 并且执行后会返回自身
function* gn(){

}
let re = gn()
console.log(re[Symbol.iterator]() === re);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

next方法的参数

// yield表达式本身是没有返回值的 返回的就是undefined
// next方法可以带一个参数这个参数会被当做 !!!上一个!!! yield表达式的返回值
function* helloGenerator(){
    let y1 = yield 'hello'
    console.log(y1);
    yield 'world'
    return 123
}

let res = helloGenerator()
// console.log(res);
console.log(res.next());
console.log(res.next(123));
console.log(res.next());
// 如果想在第一个next传入值也输出 应该怎么做?????
// 叫做从外部出入数据到内部
// 出入generator函数 返回一个函数 可以执行next
function second(gen){
    return function(){
        let res = gen()
        res.next()
        return res
    }
}
let first = second(function*(){
    console.log(`这是第一次的yield${yield}`);
})
first().next('第一次')

  
 
  • 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

for…of 循环

// return后面的通过for...of不会输出 因为是done变为了true for...of 循环就会终止
function* gen(){
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
    return 6;
}

for(let v of gen()){
    console.log(v);
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

抛出错误

 // 函数体外抛出异常在gennerator函数内部去获取
// throw函数接收的参数 通过catch去获取
let g = function*(){
    try{
        yield
    } catch(error){
        console.log(error);
    }
}
let res = g()
res.next()
res.throw('错误')
// generator函数体内抛出异常 也可以在函数体外的catch获取
let g1 = function*(){
    yield;
}
let res = g1()
res.next()
try {
    res.throw('错误')
} catch (error) {
    console.log(error);
}
// 如果内部想要获取错误 必须通过next去触发
let g2 = function*(){
    try{
        yield
    } catch(error){
        console.log(error);
    }
}
let res = g2()
res.next()
res.throw('错误')

  
 
  • 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

return用法

// return 不传参数就是undefined
function* gen(){
    yield 1
    try {
        yield 2
        yield 3
    } finally{
        yield 4
        yield 5
    }
}
let g = gen()
console.log(g.next());
console.log(g.return(4));
console.log(g.next());

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

yield* 表达式

function* first(){
    yield 1;
    yield 2;
}
function* second(){
    yield 3
    // 在这里调用firstgenerator函数应该怎么做?
    for (let i of first()){
        yield i
    }
    yield 4
}
// for...of 循环遍历第二个
// 上面可以用过 yield* 来替换
function* second(){
    yield 3
    // 在这里调用firstgenerator函数应该怎么做?
    yield* first()
    yield 4
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

generator 函数的this

function* g(){}
// 也有prototype对象
g.prototype.hello = function(){
    return 'hi'
}
let res = g()
console.log(res.hello());
console.log(res instanceof g);
//-------------------------------
function* g1(){
    this.a = 123
}
let res = g1()
res.next()
console.log(res.a);
//--------------------------------
function* f(){
    this.a = 123
    yield this.b = 234
    yield this.c = 456
}

let obj = {}
let res = f.call(obj)
console.log(res.next());
console.log(res.next());
console.log(obj.a);
console.log(obj.b);
console.log(obj.c);
//-------------------------------
function* f(){
    this.a = 123
    yield this.b = 234
    yield this.c = 456
}

// let obj = {}
let res = f.call(f.prototype)
console.log(res.next());
console.log(res.next());
console.log(res.a);
console.log(res.b);
console.log(res.c);
// 不支持new 现在让你支持new
function F(){
    return f.call(f.prototype)
}

let res = new F()
console.log(res.next());
console.log(res.next());
console.log(res.a);
console.log(res.b);
console.log(res.c);

  
 
  • 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

异步应用

function request(url){
    axios.get(url).then(res=>{
        result.next(res)
    })
}
function *get(){
    let res1 = yield request('http://127.0.0.1:2000/name.json')
    console.log(res1);
    let id = res1.data.data[0].id
    let res2 = yield request(`http://127.0.0.1:2000/wepon.json?id=${id}`)
    console.log(res2);
}

let result = get()
result.next()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。

原文链接:codeboy.blog.csdn.net/article/details/107136029

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。