zoukankan      html  css  js  c++  java
  • JavaScript闭包应用场合——控制前端接口轮训

    很多人都知道JavaScript的闭包,也知道大致是一个什么意思,但是对于闭包的应用场合不是很清楚

    最近在改造项目的过程之中修改前端接口轮训方式的时候用到了闭包驱动setTimeout来实现一个类似定时器的功能,可以开启定时器也可以关闭定时器

    代码如下

    // 创建异步轮训器(setTimeout实现),导出一个闭包对象,用于控制轮训
    createLooper (func, time = 1000, params, callback = () => { }, err = () => { }) {
        // 轮训时钟
        let timer = -1;
        // 轮训状态(开启,关闭)
        let status = true;
        // Promise化的setTimeout
        function setTimeoutPromise (func, time, params) {
            return new Promise((resolve, reject) => {
                timer = setTimeout(async () => {
                    try {
                        let result = await func(params);
                        resolve(result);
                    }
                    catch (e) {
                        reject(e);
                    }
                }, time);
            });
        }
        // 导出的用于控制轮训的闭包对象
        const closureObj = {
            start () {
                if (!status) {
                    asyncLoop();
                    status = true;    
                }
            },
            stop () {
                if (status) {
                    clearTimeout(timer);
                    status = false;
                }
            },
        };
        // 首次访问,不在轮训体之内的
        async function firstCall () {
            try {
                let result = await func(params);
                callback(result, closureObj);
                return true;
            }
            catch (e) {
                clearTimeout(timer);
                status = false;
                console.error(e.message);
                err(e, closureObj);
                return false;
            } 
        }
        // 异步轮训循环
        async function asyncLoop () {
            let status = await firstCall();
            if (status) {
                while (true) {
                    try {
                        let result = await setTimeoutPromise(func, time, params);
                        callback(result, closureObj);
                    }
                    catch (e) {
                        clearTimeout(timer);
                        status = false;
                        console.error(e.message);
                        err(e, closureObj);
                    }
                }
            }
        }
        asyncLoop();
        return closureObj;
    },

    这是一个函数,有五个参数

    第一个参数为定时器要执行的函数

    第二个参数为定时器的触发时间间隔

    第三个参数为定时器执行参数的参数

    第四个参数为获取执行函数返回值的回调

    第五个参数为错误处理的回调

    这个函数返回一个对象,这个对象内有两个方法都是闭包导出的方法

    分别是start和stop,而这两个方法都访问了函数内部的status(轮训状态)变量以及timer(setTimeout返回的Id),所以可以控制定时器开启和关闭

    正是因为闭包的能力所以我们可以调用这个函数返回的对象中的方法来控制函数内部的setTimeout的开启和关闭

    这就是我在工作中遇到的闭包的一个小的应用场所

  • 相关阅读:
    [luogu2059 JLOI2013] 卡牌游戏 (概率dp)
    [luogu1772 ZJOI2006] 物流运输 (最短路 线性dp)
    [luogu 2568] GCD (欧拉函数)
    [poj 2976] Dropping tests (分数规划 二分)
    cf掉分记——Avito Code Challenge 2018
    新博客的第一篇博文~
    [noip2011 luogu1312] Mayan游戏(模拟)
    bzoj2618 [Cqoi2006]凸多边形
    LLppdd never give up!
    我的scoi2018
  • 原文地址:https://www.cnblogs.com/jimaojin/p/10923525.html
Copyright © 2011-2022 走看看