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

Spark AR中如何从外部脚本访问异步函数内的函数?

解决Spark AR中跨脚本调用IIFE内函数的问题

嘿,我明白你卡在哪了——你把GameOver函数放在了一个异步的立即执行函数(IIFE)里面,这个函数的作用域是封闭的,所以哪怕你加了export也没用,因为export只能在模块的顶级作用域使用,没法嵌套在函数里。下面给你几个在Spark AR里可行的解决方案:

方案1:将函数挂载到模块导出的变量上

这是最直接的修改方式,只需要在IIFE外面先声明一个变量,内部把GameOver赋值给它,最后在模块顶级导出:

// UIManager.js
let GameOver; // 先在模块顶级声明变量

(async function() {
  // 这里保留你的其他初始化代码...

  // 去掉内部的export,直接赋值给外部变量
  GameOver = function(score = 0) {
      //显示游戏结束界面
      LoseScreen.hidden = false;
      //检查游戏是否包含商店
      if(GameSettings.RequireShop) {
          ShopButton.hidden = false;
      } else {
          ShopButton.hidden = true;
      }
      //设置当前界面状态
      CurrentScreen = "LoseScreen";
      //隐藏游戏界面
      GameMenuObj.hidden = true;
      //保存并显示当前得分
      Score = score;
      TotalScore += Score;
      LoseScore.text = Score.toString();
      //检查游戏是否包含排行榜或商店
      if(GameSettings.RequireleaderBoard || GameSettings.RequireShop) {
          SaveData();
      }
      //显示/刷新货币数值
      CoinText.text = TotalScore + "";
  };

  // 你的其他异步逻辑...
})();

// 在模块顶级导出这个变量
export { GameOver };

在GameManager中的调用方式:

// GameManager.js
import { GameOver } from './UIManager';

// 游戏结束时调用,传入当前得分
GameOver(currentScore);

方案2:暴露统一的UI管理接口(更规范)

如果后续还有其他UI相关函数需要跨脚本调用,这种方式更便于统一管理:

// UIManager.js
const UIManager = {}; // 定义一个统一的接口对象

(async function() {
  // 你的其他初始化代码...

  // 把GameOver作为接口对象的方法
  UIManager.GameOver = function(score = 0) {
      // 函数内容和之前一致...
  };

  // 后续可以添加更多UI方法,比如UIManager.ShowStartScreen()
})();

// 导出整个接口对象
export default UIManager;

GameManager中的调用方式:

// GameManager.js
import UIManager from './UIManager';

UIManager.GameOver(currentScore);

方案3:使用Spark AR的Signal实现事件通信(推荐最佳实践)

Spark AR自带Signal类,适合做跨脚本的事件通信,能有效解耦两个脚本的依赖关系:

// UIManager.js
import { Signal } from 'Reactive';

// 创建游戏结束信号并导出
export const onGameOver = new Signal();

(async function() {
  // 你的其他初始化代码...

  // 内部定义GameOver逻辑
  function handleGameOver(score = 0) {
      // 函数内容和之前一致...
  }

  // 监听信号,触发时执行游戏结束逻辑
  onGameOver.subscribe((score) => {
      handleGameOver(score);
  });

  // 你的其他异步逻辑...
})();

GameManager中的触发方式:

// GameManager.js
import { onGameOver } from './UIManager';

// 游戏结束时触发信号,传入当前得分
onGameOver.emit(currentScore);

这种方式的好处是,两个脚本不需要直接依赖彼此的函数,而是通过事件传递信息,更符合Spark AR的组件化开发思路。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:32:45