• 在微信小程序上做一个「博客园年度总结」:解决前端获取接口数据太慢的一种思路


    先介绍下目前代码中后端是如何给前端提供数据的:

    1、构造一个函数A,这个方法中会调用博客园「获取随笔列表」接口,取到数据作进一步处理,然后把结果返出去;

    2、使用flask创建一个接口,这个接口会调用函数A,获取A的结果,然后通过这个接口把前端需要数据返出去;

    3、小程序会调用我创建好的接口来获取数据,展示在前端;

     

    在调试过程中,发现「获取随笔列表」接口响应时间比较长,大概有6s左右的样子

    这就导致在首次打开小程序,进入年度总结页面时,肉眼可见的要等一会儿才能加载出数据,体验不太好

     

    Q:有没有什么方法可以快点让前端接收到数据呢?

    A1、第一个想法

    后端调用博客园接口获取到数据后,把数据缓存起来,然后前端每次调接口时,是从缓存中取数据;

    结果:查了一下如何使用python或者flask做数据缓存,但是没有找到比较好的实现方法

    感兴趣的朋友可以看看这篇文章:如何在 Python 程序中实现缓存

     

    A2、第二个想法

    从「随笔列表接口」请求到数据后,先把数据存到一个文件中(比如json文件),然后在给前端提供的接口中,读取文件中的数据

    这样的话,就不用每次都对博客园的接口发起请求了,经过试验,前端获取数据的速度确实快了很多

     

    至于如何更新文件中的数据,可以通过异步方式实现,每次从文件中读取数据后,再调用一下向文件中写入数据的方法

    这样就保证了文件中数据的实时性

     

    具体实现过程

    在存储博客园接口返回数据时,我没有使用json文件,而是用到了python的pickle模块

    1、定义写入、读取文件内容的方法

    public.py

    # coding: utf-8
    """
    author: hmk
    detail: 
    create_time: 
    """
    import os
    import pickle
    
    
    def get_path():
        """获取文件所在目录"""
        BASE_PATH_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
        return BASE_PATH_DIR
    
    
    def push_pkl(file_path, data):
        with open(get_path() + file_path, 'wb') as f:
            pickle.dump(data, f)
    
    
    def read_pkl(file_path):
        with open(get_path() + file_path, 'rb') as f:
            data = pickle.load(f)
            return data

     

    2、修改get_blogs_api()函数

    之前的get_blogs_api()函数在处理好随笔数据后就直接返出去了,这里我们不返出去,而是把结果写到文件中

    同时我们后续要异步调用这个函数,所以也要额外进行处理

    定义一个装饰器 async_fun

    def async_fun(f):
        def wrapper(*args, **kwargs):
            thr = Thread(target=f, args=args, kwargs=kwargs)
            thr.start()
    
        return wrapper

    修改get_blogs_api(),使用@async_fun装饰这个方法,

        @async_fun
        def get_blogs_api(self, blog_name):
            """获取个人随笔列表接口"""
    
            flag = True
            try:
                ... ...
                ... ...
                ... ...
                res = {
                    "first_blog": first_blog,  # 发布的第一篇博客
                    "view_max_10": view_max_10,  # 浏览量前10的文章
                    "now_year_blog_sum": now_year_blog_sum,  # 2022年新增博客总数
                    "month_result": month_result,  # 2022年每月博客新增数量
                    "year_result": year_result  # 每年博客新增数量
                }
           
                push_pkl('/api_tools/cn_blogs.pkl', res)  # 把结果写到文件中
    
    
            except Exception as e:
                raise e

     

    3、再写一个方法,从文件中读取数据

        def get_blogs(self):
    
            data = read_pkl('/api_tools/cn_blogs.pkl')
    
            # print(data)
    
            return data

     

    4、flask接口方法中,调用get_blogs()get_blogs_api()

    class GetBlogs(Resource):
        """接口:获取个人随笔列表"""
    
        @staticmethod
        def get():
            blog_app = cn_blogs.conf["cn_blogs"]["blogApp"]  # request.args.get("blog_app")
            cn_blogs.get_blogs_api(blog_app) # 先调用向文件写入数据的方法
            res = cn_blogs.get_blogs() # 调用读取文件数据的方法
            return res

    实际运行时,前端调用这个flask接口后,会立刻得到数据,不用等待get_blogs_api()执行成功

    因为get_blogs_api()会异步执行,运行成功后把从博客园接口获取到新数据再写入文件,

    这样在下次前端调用接口时,拿到的就会是最新的数据

     

  • 相关阅读:
    程序员缓解工作压力的一些方法
    Python3 错误和异常一篇就够了
    unix多进程多线程
    OPCHDA接口
    ElasticSearch查询
    Redis 笔记 01:入门篇
    C语言 用字符串比较函数cmp来做一个门禁:账号密码是否匹配 (干货满满)
    What are the advantages of pipes over temporary files?
    制作一个简单HTML大学生抗疫感动专题网页(HTML+CSS)
    男孩姓岳取什么名字好听
  • 原文地址:https://www.cnblogs.com/hanmk/p/16832147.html