• es6-16 Generator


    Generator是一个迭代器生成函数,其返回值是一个迭代器(Iterator),可用于异步调用。

    格式演示

    {
        let tell = function* () {
            yield 'a'
            yield 'b'
            return 'c'
        }
        let k = tell()
    
        // 通过 next() 依次执行 yield
        console.log(k.next()) // {value: "a", done: false}
        console.log(k.next()) // {value: "b", done: false}
        console.log(k.next()) // {value: "c", done: true}
        console.log(k.next()) // {value: undefined, done: true}
    }

    Object 是没有 iterator 的, 是不能使用 for of 的, 这里使用创建 Generator 函数的方式

    {
        let obj = {}
        obj[Symbol.iterator] = function* () {
            yield 1
            yield 2
            yield 3
        }
    
        for (let key of obj) {
            console.log(key) // 1 2 3
        }
    }

    generator 优势点 状态机

    {
        // generator 优势点 状态机
        let state = function* () {
            while(1) {
                yield 'A'
                yield 'B'
                yield 'C'
            }
        }
        let status = state()
        console.log(status.next()) // {value: "A", done: false}
        console.log(status.next()) // {value: "B", done: false}
        console.log(status.next()) // {value: "C", done: false}
        console.log(status.next()) // {value: "A", done: false}
        console.log(status.next()) // {value: "B", done: false}
    }

    async 函数就是 Generator 函数的语法糖

    {
        let timeout = function (ms) {
            return new Promise((resolve, reject) => {
                setTimeout(resolve, 1000);
            })
        }
    
        let asyncPrint = async function (value, ms) {
            await timeout(ms).then(() => {
                console.log('我是异步处理');
            });
            console.log(value);
        }
    
        asyncPrint('hello world', 1000);
        // 执行结果:
        // 1秒之后,先打印出"我是异步处理",然后打印出"hello world"
    }

    抽奖次数限制示例

    {
        let draw = function(count) {
            // 抽奖逻辑......
            console.info(`剩余${count}次`)
        }
    
        let residue = function* (count) {
            while (count > 0) {
                count--
                yield draw(count)
            }
        }
    
        let star = residue(5)
        let btn = document.createElement('button')
        btn.id = 'start'
        btn.textContent = '抽奖'
        document.body.appendChild(btn)
        document.getElementById('start').addEventListener('click', function(){
            star.next()
        })
    }

    长轮询

    {
        let ajax = function* () {
            yield new Promise(function(resolve, reject){
                setTimeout(function () {
                    resolve({code: 0})
                }, 2000)
            })
        }
    
        let pull = function () {
            let generator = ajax()
            let step = generator.next()
            step.value.then(function(d){
                if (d.code != 0) {
                    setTimeout(function () {
                        console.log('wait')
                        pull()
                    }, 1000)
                } else {
                    console.log(d)
                }
            })
        }
        pull()
    }
  • 相关阅读:
    【BZOJ4826】【HNOI2017】影魔(扫描线,单调栈)
    【BZOJ4540】【HNOI2016】序列(莫队)
    【NOIP2017】列队(Splay)
    ZJOI2018酱油记
    【BZOJ4828】【HNOI2017】大佬(动态规划)
    【NOIP2017】宝藏(状态压缩,动态规划)
    【HDU4336】Card Collector (动态规划,数学期望)
    【HDU4652】Dice(数学期望,动态规划)
    【BZOJ4945】【NOI2017】游戏(搜索,2-sat)
    【BZOJ3714】Kuglarz(最小生成树)
  • 原文地址:https://www.cnblogs.com/helzeo/p/11844153.html
Copyright © 2020-2023  润新知