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

点击取消Promise时出现"undefined is not a function"错误求助

问题原因及解决办法

核心问题

你碰到的undefined is not a function错误,本质是在promiseReject被赋值前就调用了它——比如先点拒绝按钮,或者go函数还没执行到sleep逻辑时就触发拒绝操作。另外当前写法还存在多次调用go时,promiseReject会被覆盖的问题,可能导致旧的定时器无法被正确清理。

修复方案

1. 最小改动:增加调用前判断

不想大改代码的话,先给拒绝按钮加个判断,避免调用未定义的函数,同时在sleep执行完成或取消后重置变量:

let promiseReject

const sleep = seconds => new Promise((resolve, reject) => {
  const timeoutId = setTimeout(() => {
    resolve()
    promiseReject = undefined // 超时后重置
  }, seconds * 1000)

  promiseReject = () => {
    clearTimeout(timeoutId)
    reject()
    promiseReject = undefined // 取消后重置
  }
})

const go = async () => {
  try {
    await sleep(10)
    // 超时完成后的逻辑
  } catch (err) {
    // 被取消后的逻辑
    console.log('睡眠已取消')
  }
}

// 触发睡眠的按钮
<TouchableOpacity
  onPress={() => {
    go()
  }}
>
</TouchableOpacity>

// 取消睡眠的按钮
<TouchableOpacity
  onPress={() => {
    promiseReject?.() // 用可选链避免调用undefined
  }}
>
</TouchableOpacity>

2. 推荐方案:用类管理睡眠实例

全局变量容易出问题,用类封装每个睡眠实例的状态和操作,避免覆盖问题:

class SleepController {
  constructor() {
    this.rejectFn = null
    this.timeoutId = null
  }

  sleep(seconds) {
    return new Promise((resolve, reject) => {
      this.rejectFn = reject
      this.timeoutId = setTimeout(() => {
        resolve()
        this._reset()
      }, seconds * 1000)
    })
  }

  cancel() {
    if (this.rejectFn && this.timeoutId) {
      clearTimeout(this.timeoutId)
      this.rejectFn()
      this._reset()
    }
  }

  _reset() {
    this.rejectFn = null
    this.timeoutId = null
  }
}

// 创建一个睡眠控制器实例
const sleepController = new SleepController()

const go = async () => {
  try {
    await sleepController.sleep(10)
    console.log('超时完成')
  } catch (err) {
    console.log('睡眠被取消')
  }
}

<TouchableOpacity
  onPress={() => {
    go()
  }}
>
</TouchableOpacity>

<TouchableOpacity
  onPress={() => {
    sleepController.cancel()
  }}
>
</TouchableOpacity>

关键提醒

一定要用try/catch包裹await sleep,这样reject时才能捕获到取消状态,避免出现未处理的Promise报错。

内容的提问来源于stack exchange,提问作者JackFrost

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:50:07