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

Cocos Creator JavaScript中cc.resources.load回调不生效,外部无法读取修改后的属性值

问题原因

cc.resources.load()是异步加载API,调用后不会立刻执行回调,会先继续执行回调后面的同步代码。你在回调外部读取参数时,资源还没加载完成,回调函数还没触发,参数还没被修改,所以读到的是初始值,并不是修改没生效。
另外还有一种小概率原因:回调函数没有使用箭头函数,导致内部this指向不是当前组件实例,赋值的其实是其他对象的属性,自然不会修改到组件的properties参数。

你提供的代码截图参考:
代码截图

错误写法复现
properties: {
  targetRes: null // properties定义的参数
},
start () {
  // 调用资源加载
  cc.resources.load('textures/testImg', cc.SpriteFrame, function (err, res) {
    // 此处如果没用箭头函数,this指向错误,就算指向正确,执行时机也晚于下面的log
    this.targetRes = res
  })
  // 此处同步执行,早于回调触发,读到的还是初始值null
  console.log(this.targetRes) 
}
解决方案
  • 方案1:逻辑内移
    所有需要用到修改后参数的逻辑,全部放到加载回调内部执行,保证参数赋值完成后再运行相关逻辑,同时注意用箭头函数保留组件this指向:
    cc.resources.load('textures/testImg', cc.SpriteFrame, (err, res) => {
      if (err) {
        console.error('资源加载失败', err)
        return
      }
      this.targetRes = res
      // 后续用到targetRes的逻辑都写在这里
      this.getComponent(cc.Sprite).spriteFrame = this.targetRes
    })
    
    如果你坚持用普通函数作为回调,需要提前存储this指向:
    let self = this
    cc.resources.load('textures/testImg', cc.SpriteFrame, function (err, res) {
      if (err) return
      self.targetRes = res
      // 后续逻辑写在这里
    })
    
  • 方案2:async/await异步转同步写法
    用Promise封装加载方法,用async/await语法让异步代码按同步顺序执行,更方便维护多异步串联的逻辑:
    // 封装通用加载方法
    loadAsset (path, assetType) {
      return new Promise((resolve, reject) => {
        cc.resources.load(path, assetType, (err, res) => {
          err ? reject(err) : resolve(res)
        })
      })
    },
    // 调用的生命周期方法或自定义方法加async修饰
    async start () {
      try {
        // await会等待加载完成再执行后续代码
        this.targetRes = await this.loadAsset('textures/testImg', cc.SpriteFrame)
        // 此处已经完成赋值,可以正常读取
        console.log(this.targetRes)
      } catch (e) {
        console.error('加载出错', e)
      }
    }
    
  • 方案3:事件通知
    如果需要跨方法、跨组件使用这个参数,可以在赋值完成后发送自定义事件,监听事件的位置再读取参数执行逻辑:
    // 回调内赋值完成后发送事件
    cc.resources.load('textures/testImg', cc.SpriteFrame, (err, res) => {
      if (err) return
      this.targetRes = res
      this.node.emit('res-loaded')
    })
    
    // 其他位置监听事件后再读取
    onEnable () {
      this.node.on('res-loaded', this.onResLoaded, this)
    },
    onResLoaded () {
      console.log(this.targetRes) // 已完成赋值,读取正常
    }
    
注意事项

不要依赖异步操作的执行顺序,所有依赖异步结果的逻辑都要保证在异步完成后触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:57:02