Node.js报错:Uncaught (in promise) TypeError: promisify is not a function 求解
解决
promisify is not a function错误及Google Sheets操作优化 你遇到的这个错误,主要有两个可能的原因:要么是promisify的导入/使用方式有问题,要么是你在用的google-spreadsheet版本太旧,手动处理Promise的方式容易踩坑。作为Node.js新手,我推荐你优先用更简洁的新版方案,同时也会给你旧版的修复方法。
方案一:升级到新版google-spreadsheet(推荐)
新版的google-spreadsheet(v3及以上)已经原生支持Promise,完全不需要手动用promisify转换,代码会简单很多,也不容易出错。
步骤1:升级npm包
在终端运行:
npm install google-spreadsheet@latest
步骤2:修改代码适配新版API
新版的导入方式和部分API有小变化,调整后的代码如下:
// 注意新版的导入是解构式的 const { GoogleSpreadsheet } = require('google-spreadsheet'); const creds = require('./client_secret.json'); async function accessSpreadsheet(){ const doc = new GoogleSpreadsheet(MY_GOOGLESHEET_ADDRESS); // 直接await,方法原生返回Promise await doc.useServiceAccountAuth(creds); const info = await doc.getInfo(); // 新版用sheetsByIndex替代旧版的worksheets const sheet = info.sheetsByIndex[0]; const rows = await sheet.getRows({ offset:1 }); // 用for...of替代forEach,方便处理异步的save操作 for(const row of rows){ if(row.userid === 'dog'){ let num = parseInt(row.point, 10); num += 1; row.point = num; // save方法也原生支持await await row.save(); } } }
方案二:修复旧版代码的promisify问题
如果你不想升级包,那需要注意两个关键点:一是确保promisify的导入正确,二是必须绑定方法的上下文(this)——因为旧版google-spreadsheet的方法是依赖实例上下文的,直接promisify会丢失this,导致报错。
修复后的代码:
const GoogleSpreadsheet = require('google-spreadsheet'); // 改用完整导入util模块,避免解构可能的变量冲突 const util = require('util'); const creds = require('./client_secret.json'); async function accessSpreadsheet(){ const doc = new GoogleSpreadsheet(MY_GOOGLESHEET_ADDRESS); // 用call绑定doc作为方法的this上下文 await util.promisify(doc.useServiceAccountAuth).call(doc, creds); const info = await util.promisify(doc.getInfo).call(doc); const sheet = info.worksheets[0]; const rows = await util.promisify(sheet.getRows).call(sheet, { offset:1 }); // 同样,row.save()也要绑定上下文并await for(const row of rows){ if(row.userid === 'dog'){ let num = parseInt(row.point, 10); num += 1; row.point = num; await util.promisify(row.save).call(row); } } }
额外提示
- 尽量用
const/let替代var,避免变量提升带来的问题; - 处理异步操作时,
forEach不能正确等待异步任务完成,改用for...of更可靠; - 升级新版包后,建议参考官方文档的最新示例,API更直观,适合新手学习。
内容的提问来源于stack exchange,提问作者p6Chen
相关产品推荐
相关产品推荐

