You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:37:37