在微信小程序上做一個「博客園年度總結」:解決前端獲取接口數據太慢的一種思路

先介紹下目前代碼中後端是如何給前端提供數據的:

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()會異步執行,運行成功後把從博客園接口獲取到新數據再寫入文件,

這樣在下次前端調用接口時,拿到的就會是最新的數據

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章