Node.js中setInterval调用异步函数遇self.gotUser不是函数错误排查
问题排查:setInterval中调用异步函数的this指向错误
问题场景
在setInterval中传入originalDetails和filePath调用异步函数,编写createUser函数设置3秒延迟执行(因findDetails需要延迟),但出现两个错误:
self.gotUser is not a function- 报错栈包含
Timeout.createUser [as _onTimeout]
原代码
const findDetails = require("./findDetails"); async createUser(originalDetails,filePath){ return new Promise(async (resolve reject)=>{ findDetails(filePath); setInterval(this.findUser,3000,originalDetails,filePath); }) } async findUser(originalDetails,filePath){ return new Promise(async (resolve reject)=>{ // some code here var self=this; await self.gotUser(originalDetails); // 报错位置 return resolve(); }); } async gotUser(originalDetails){ return new Promise(async (resolve, reject)=>{ let inputValue; // some coding part here return resolve(); }); }
报错信息
/Users/servive_project/provide_service.js:300:18 await self.gotUser(originalDetails); ^ TypeError: self.gotUser is not a function at /Users/servive_project/provide_service.js:300:18 at new Promise (<anonymous>) at Timeout.createUser [as _onTimeout] (/Users/servive_project/provide_service.js:288:12) at listOnTimeout (node:internal/timers:561:11) at processTimers (node:internal/timers:502:7)
错误原因分析
- this指向丢失:
setInterval调用this.findUser时,this会被绑定到Timeout对象(即报错中的Timeout.createUser),而非原类/对象实例,导致findUser里的self无法访问到实例方法gotUser。 - 冗余Promise嵌套:
async函数本身已返回Promise,无需再手动嵌套new Promise,这不仅冗余还可能导致逻辑混乱。 - 语法错误:原代码中
new Promise(async (resolve reject)=>{里resolve和reject之间缺少逗号,属于语法问题。 - setInterval误用:如果仅需延迟执行一次,
setInterval会重复执行(需手动清除),不符合预期,应使用setTimeout。
修复方案及修正代码
核心修复点
- 用箭头函数或
bind绑定this,确保回调函数中的this指向原实例。 - 移除
async函数中冗余的new Promise包裹。 - 替换
setInterval为setTimeout(按需)。 - 修正语法错误。
修正后的代码
const findDetails = require("./findDetails"); async createUser(originalDetails, filePath) { findDetails(filePath); // 用箭头函数保留this指向,使用setTimeout实现单次延迟执行 return new Promise((resolve) => { setTimeout(async () => { await this.findUser(originalDetails, filePath); resolve(); }, 3000); }); } async findUser(originalDetails, filePath) { // some code here // async函数直接执行逻辑,无需嵌套Promise await this.gotUser(originalDetails); } async gotUser(originalDetails) { let inputValue; // some coding part here // async函数自动返回Promise,无需手动创建 }
额外说明
如果确实需要重复执行findUser,则需保留setInterval并手动清理定时器,同时绑定this:
async createUser(originalDetails, filePath) { findDetails(filePath); // 绑定this到findUser const timer = setInterval(this.findUser.bind(this), 3000, originalDetails, filePath); // 后续可通过clearInterval(timer)停止执行 }
内容的提问来源于stack exchange,提问作者Arun Yadav
相关产品推荐
相关产品推荐

