使用google-api-nodejs-client调用Google Sheets API如何避免重复获取客户端
优化方案
方案1:改造认证模块实现客户端单例缓存
这个方案改动最小,完全不需要修改现有业务函数的调用逻辑,只需要调整googleAuth.js的实现,复用同一个客户端实例即可:
const { google } = require("googleapis"); const auth = new google.auth.GoogleAuth({ keyFile: "credentials.json", scopes: "https://www.googleapis.com/auth/spreadsheets", }); // 新增缓存变量存储已初始化的sheets客户端 let cachedSheetsClient = null; const getAuthClient = async () => { try { return await auth.getClient(); } catch (error) { console.error(error); } }; const sheetsClient = async () => { // 有缓存直接返回,避免重复初始化 if (cachedSheetsClient) return cachedSheetsClient; const client = await getAuthClient(); cachedSheetsClient = await google.sheets({ version: "v4", auth: client }); return cachedSheetsClient; }; module.exports = { sheetsClient };
Google官方的Auth实例自带token自动刷新逻辑,缓存的客户端不会出现认证过期的问题,多次调用sheetsClient()只会触发一次初始化,后续都直接返回缓存实例,完全兼容你现有业务代码的写法,不需要做任何其他调整。
方案2:高阶函数封装业务逻辑(适合多API场景扩展)
如果后续还要对接Google其他服务,可以用高阶函数把获取客户端的逻辑统一抽离,避免每个业务函数都写重复的获取逻辑:
const { sheetsClient } = require("./googleAuth"); // 高阶函数:自动注入sheets客户端 const withSheets = (handler) => { return async (...args) => { const client = await sheetsClient(); return handler(client, ...args); } } // 业务函数只需要专注逻辑,不需要处理客户端获取 const createSheet = withSheets(async (client, name) => { const sheet = await client.spreadsheets.create({ resource: { properties: { title: name, }, }, }); return sheet; }); const updateSheet = withSheets(async (client, name) => { const sheet = await client.spreadsheets.update({ resource: { properties: { title: name, }, }, }); return sheet; }); const deleteSheet = withSheets(async (client, name) => { const sheet = await client.spreadsheets.delete({ resource: { properties: { title: name, }, }, }); return sheet; });
这种写法的扩展性更强,如果后续要加其他Google服务的封装,只需要新增对应的高阶函数即可,业务函数的逻辑更纯粹,没有冗余的客户端获取代码。
批量操作场景补充
如果同一个业务流程需要连续调用多个sheet操作,也可以主动一次获取客户端后复用,进一步减少不必要的判断:
const { sheetsClient } = require("./googleAuth"); const batchOperateSheet = async (name) => { // 一次获取,多次使用 const client = await sheetsClient(); await createSheet(client, name); await updateSheet(client, name); await deleteSheet(client, name); }
内容的提问来源于stack exchange,提问作者HelloWorld
相关产品推荐
相关产品推荐

