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

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());

与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);

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('第一次')

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);
}

抛出错误

 // 函数体外抛出异常在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('错误')

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());

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
}

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);

异步应用

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()

你可能感兴趣的:(#,Javascript,高级篇)