zoukankan      html  css  js  c++  java
  • es6+最佳入门实践(10)

    10.Generator

    10.1.Generator是什么?

    Generator函数是ES6提供的一种异步编程解决方案。在它的内部封装了多个状态,因此,又可以理解为一种状态机,执行Generator函数后返回一个迭代器对象,使用这个迭代器对象可以遍历出Generator函数内部的状态

    Generator函数和传统函数的不同点有:1 函数定义的时候,function关键字后面加“*”, 2 内部使用yield关键字定义内部状态

    
    function* HelloGenerator() {
        yield "状态1";
        yield "状态2";
        yield "状态3";
        yield "状态4";
    }
    
    let hg = HelloGenerator();
    console.log(hg.next());  //{value: "状态1", done: false}
    console.log(hg.next());  //{value: "状态2", done: false}
    console.log(hg.next());  //{value: "状态3", done: false}
    console.log(hg.next());  //{value: "状态4", done: false}
    console.log(hg.next());  //{value: undefined, done: true}
    

    Generator函数被调用后,并不会立即执行完成,而是会在遇到yield关键字后暂停,返回的也不是函数的运行结果,而是一个执行内部状态的指针对象(Iterator对象)

    注意1: next方法内可以传参数,这个参数的值作为上一次状态的返回值

    
    function* HelloGenerator() {
        let result = yield "状态1";
        console.log(result);
        yield "状态2";
        yield "状态3";
        yield "状态4";
    }
    
    let hg = HelloGenerator();
    console.log(hg.next());
    console.log(hg.next('nodeing'));  
    
    

    注意2: 可以使用for...of来遍历Generator内部状态

    
    function* HelloGenerator() {
    
        yield "状态1";
        yield "状态2";
        yield "状态3";
        yield "状态4";
    }
    
    let hg = HelloGenerator();
    
    for( let i of hg){
        console.log(i);
    }
    
    

    注意3: 对象没有Symbol.Iterator属性,我们可以手动添加,让其具有Iterator接口

    let obj = {};
    function* gen() {
        yield 1;
        yield 2;
        yield 3;
        yield 4;
    }
    obj[Symbol.iterator] = gen;
    
    for(let a of obj){
        console.log(a);
    }
    
    

    10.2.Generator应用

    1.限制抽奖次数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <button id="btn">抽奖</button>
    <input type="text" id="ipt">
    <script>
        let oBtn = document.getElementById('btn');
        let oIpt = document.getElementById('ipt');
        let start = gen(5);
        let timmer = null;
        oBtn.onclick = () => {
            start.next();
        };
        function draw(count) {
            clearInterval(timmer);
            let num = Math.floor(Math.random() * 30);
            let prize = 0;
    
            timmer = setInterval(()=>{
                prize++;
                if( num === prize){
                    clearInterval(timmer);
                    alert("还可以抽"+count+"次");
                    return;
                }
                oIpt.value = prize;
            }, 100);
    
    
        }
        
        function* gen(count) {
            while (count > 0){
                count--;
                yield draw(count);
            }
        }
    </script>
    </body>
    </html>
    

    2.异步读取文件

    const fs = require('fs');
    
    function readFile(path) {
        return new Promise((resolve, reject) => {
            fs.readFile(path, (err, data) => {
                if(err){
                    reject(err)
                }else {
                    resolve(data)
                }
            })
        })
    }
    
    function* asyncFile() {
        yield readFile('a.txt');
        yield readFile('b.txt');
        yield readFile('c.txt');
    }
    
    let gen = asyncFile();
    gen.next().value.then((data)=>{
        console.log(data.toString());
        return gen.next().value;
    }).then((data2)=>{
        console.log(data2.toString());
        return gen.next().value;
    }).then((data3)=>{
        console.log(data3.toString())
    
    });
    

    如果觉得上面的写法还比较麻烦的话,我们可以引入一个co模块,让aysncFile里面的代码自动执行

    const co = require('co');
    
    function* asyncFile() {
        let a = yield readFile('a.txt');
        let b = yield readFile('b.txt');
        let c = yield readFile('c.txt');
        console.log(a.toString(), b.toString(), c.toString())
    }
    co(asyncFile()).then(()=>{
        console.log('文件读取完成')
    });
    

    视频教程地址:http://edu.nodeing.com/course/50

  • 相关阅读:
    水晶报表参数字段在代码中赋值
    存储过程编写经验和优化措施
    积分与排名
    大话处理器
    抽象数学
    开普勒:天空的立法者
    Scalable Face Image Retrieval with IdentityBased Quantization and Multireference Reranking
    配色辞典
    图像识别顶级赛事
    Information Geometry
  • 原文地址:https://www.cnblogs.com/dadifeihong/p/10358130.html
Copyright © 2011-2022 走看看