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

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)

错误原因分析

  1. this指向丢失:setInterval调用this.findUser时,this会被绑定到Timeout对象(即报错中的Timeout.createUser),而非原类/对象实例,导致findUser里的self无法访问到实例方法gotUser。
  2. 冗余Promise嵌套:async函数本身已返回Promise,无需再手动嵌套new Promise,这不仅冗余还可能导致逻辑混乱。
  3. 语法错误:原代码中new Promise(async (resolve reject)=>{里resolve和reject之间缺少逗号,属于语法问题。
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:01:05