<think>我们正在处理一个复杂的 Cocos Creator 项目,其中包含多个模块和环境修复代码。根据之前的错误和需求,我们需要对代码进行以下关键修改:
1. **修复 `EngineReady.safeAccess` 的 Promise 处理**:确保在同步路径中返回 Promise,避免 `.catch` 调用在 undefined 上。
2. **增强环境修复函数 `ensureGlobalEnvironment`**:确保全局对象(如 self、window)在所有环境下都可用,特别是在 Cocos Creator 原生平台。
3. **优化 SDK 加载逻辑**:处理路径问题,并确保在加载 SDK 前全局环境已修复。
4. **修复 `UI_Entry` 组件中的错误处理**:确保 `EngineReady.safeAccess` 返回的是一个 Promise,以便可以调用 `.catch`。
我们将对以下部分进行修改:
### 1. 修改 `EngineReady.safeAccess` 方法
在同步路径中,我们返回一个已解决的 Promise 或捕获错误并返回拒绝的 Promise,这样调用者总是可以调用 `.catch`。
### 2. 在 `UI_Entry` 的 `onLoad` 方法中,确保处理 `safeAccess` 返回的 Promise
即使同步执行,我们也返回 Promise,因此可以安全地使用 `.catch`。
### 3. 增强 `ensureGlobalEnvironment` 函数
在加载 SDK 之前和之后都调用该函数,确保全局对象(尤其是 `self`)存在。
### 4. 修改 `loadScript` 函数
处理 Cocos Creator 原生平台的脚本加载,使用 `cc.sys.__globalAdapter.require`。
### 5. 修改 `initGravityEngine` 函数
确保在全局范围内找到 `GravityEngine` 类。
### 6. 修改 `gameMainEntry` 函数
在调用 `EngineReady.safeAccess` 时,使用 `await` 或 `.catch` 处理错误。
由于代码量很大,我将提供修改后的完整代码。请注意,为了节省篇幅,我只会修改关键部分,并在代码中通过注释标出修改点。
```javascript
// ====== 环境修复与全局对象安全 ======
(function() {
// ... [保持不变] ...
})();
// ====== 引擎初始化保护系统 ======
const EngineReady = (function() {
// ... [变量声明保持不变] ...
return {
// ... [getter 保持不变] ...
init() {
// ... [保持不变] ...
},
safeAccess(callback) {
if (this.isReady) {
try {
const result = callback();
// 修改点:确保返回 Promise
if (result instanceof Promise) {
return result;
}
return Promise.resolve(result);
} catch (e) {
console.error('[EngineSafe] Sync error:', e);
return Promise.reject(e);
}
} else {
return this.promise.then(callback).catch(e => {
console.error('[EngineSafe] Async error:', e);
return Promise.reject(e);
});
}
}
};
})();
EngineReady.init();
// ====== 游戏主入口 ======
async function gameMainEntry() {
// ... [保持不变] ...
}
// ... [displayErrorFallback 保持不变] ...
// ====== SDK加载器增强版 ======
async function loadGravityEngineSDK() {
// ... [sdkPaths 保持不变] ...
for (const path of sdkPaths) {
try {
// 关键修复:在加载 SDK 前确保全局对象完整
ensureGlobalEnvironment();
// JSB 特殊处理:使用 require 加载
if (cc.sys.isNative && cc.sys.__globalAdapter?.require) {
cc.sys.__globalAdapter.require(path);
console.log('[SDK] Native require loaded:', path);
} else {
await loadScript(path);
console.log('[SDK] Loaded from:', path);
}
// 关键修复:加载后再次检查全局对象
ensureGlobalEnvironment();
initGravityEngine();
return;
} catch (e) {
console.warn('[SDK] Load failed:', path, e.message);
}
}
// ... [保持不变] ...
}
function ensureGlobalEnvironment() {
// ... [保持不变,但确保 self 被正确设置] ...
// 特别修复:确保 self 被定义为全局对象
if (typeof self === 'undefined') {
console.warn('[GlobalFix] self is undefined, patching...');
Object.defineProperty(globalObj, 'self', {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
// ... [其他全局对象修复] ...
}
function loadScript(path) {
return new Promise((resolve, reject) => {
// ... [优先使用 Cocos 的加载系统,保持不变] ...
});
}
function initGravityEngine() {
let GravityEngine = null;
// 修改点:从全局对象中获取 GravityEngine
if (typeof globalThis.GravityEngine === 'function') {
GravityEngine = globalThis.GravityEngine;
} else if (typeof window.GravityEngine === 'function') {
GravityEngine = window.GravityEngine;
} else if (typeof global.GravityEngine === 'function') {
GravityEngine = global.GravityEngine;
} else if (typeof self.GravityEngine === 'function') {
GravityEngine = self.GravityEngine;
} else {
console.error('[SDK] GravityEngine not found in any global objects');
return;
}
// ... [初始化代码保持不变] ...
}
// ... [handleSDKLoadFailure 和 loadStartScene 保持不变] ...
// ====== UI_Entry组件 ======
const { ccclass, property } = cc._decorator;
@ccclass
export default class UI_Entry extends cc.Component {
// ... [属性声明保持不变] ...
onLoad() {
// 修改点:确保 safeAccess 返回 Promise,并处理 catch
EngineReady.safeAccess(() => {
try {
cc.director.getCollisionManager().enabled = true;
this._show();
} catch (e) {
console.error('[UI] onLoad error:', e);
this.startLoadGame();
// 抛出错误以便 catch 捕获
throw e;
}
}).catch(e => {
// 这里捕获到错误(包括同步路径中抛出的错误)
console.error('[UI] Engine access error:', e);
this.startLoadGame();
});
}
// ... [其他方法保持不变] ...
}
// ====== 启动游戏 ======
if (cc?.game?.run) {
cc.game.run(() => {
ensureGlobalEnvironment();
gameMainEntry();
});
} else {
setTimeout(() => {
ensureGlobalEnvironment();
gameMainEntry();
}, 1000);
}
```
### 修改点总结
1. **`EngineReady.safeAccess`**:
- 在同步路径中,如果回调函数返回非 Promise,则用 `Promise.resolve` 包装。
- 如果回调函数抛出错误,则返回 `Promise.reject`。
2. **`UI_Entry.onLoad`**:
- 使用 `.catch` 来捕获 `safeAccess` 返回的 Promise 的错误。
- 在同步错误中,我们重新抛出错误,以便在 `.catch` 中捕获。
3. **`ensureGlobalEnvironment`**:
- 特别确保 `self` 被定义为全局对象,因为一些 SDK 可能依赖 `self`。
4. **`initGravityEngine`**:
- 修改了查找 `GravityEngine` 的顺序,首先检查 `globalThis`,然后依次是 `window`、`global` 和 `self`。
5. **其他**:
- 在游戏主入口和 SDK 加载中,我们确保在关键点调用 `ensureGlobalEnvironment`。
### 完整代码
由于整个代码很长,我将按照上述修改点提供完整的代码。请注意,为了简洁,我删除了部分重复的注释,但保留了关键部分。
```javascript
// ====== 环境修复与全局对象安全 ======
(function() {
// 安全获取全局对象的函数(支持严格模式和所有环境)
const getGlobalObject = () => {
// 1. 优先使用现代标准 globalThis
if (typeof globalThis !== 'undefined') return globalThis;
// 2. 处理严格模式限制
try {
const globalFromFn = Function('return this')();
if (globalFromFn) return globalFromFn;
} catch (e) {
console.warn('[EnvFix] Function constructor blocked in strict mode');
}
// 3. 环境特定对象
if (typeof global !== 'undefined') return global; // Node.js
if (typeof window !== 'undefined') return window; // 浏览器
if (typeof self !== 'undefined') return self; // Web Worker
// 4. Cocos Creator 原生环境特殊处理
if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) {
return cc.sys.__globalAdapter;
}
// 5. 最后手段:创建新的全局对象
console.error('[EnvFix] Unable to determine global object, creating new');
return {};
};
const globalObj = getGlobalObject();
// 修复关键全局变量(使用 Object.defineProperty 防止覆盖)
const defineGlobal = (name, value) => {
if (typeof globalObj[name] === 'undefined') {
Object.defineProperty(globalObj, name, {
value,
writable: true,
configurable: true,
enumerable: true
});
console.log(`[EnvFix] Defined global: ${name}`);
}
};
// 定义关键全局对象
defineGlobal('global', globalObj);
defineGlobal('self', globalObj);
defineGlobal('globalThis', globalObj);
defineGlobal('window', globalObj);
// 原生平台特殊处理
if (cc && cc.sys && cc.sys.isNative) {
// 确保 XMLHttpRequest 存在
if (typeof XMLHttpRequest === 'undefined') {
defineGlobal('XMLHttpRequest', function() {
return cc.loader.getXMLHttpRequest();
});
}
// 确保 document 对象存在
if (typeof document === 'undefined') {
defineGlobal('document', {
createElement: () => ({ appendChild: () => {} }),
head: { appendChild: () => {} },
body: { appendChild: () => {} }
});
}
// 确保 location 对象存在
if (typeof location === 'undefined') {
defineGlobal('location', {
href: 'file://',
protocol: 'file:',
hostname: 'localhost',
host: 'localhost',
origin: 'file://'
});
}
console.log('[EnvFix] Native environment patched');
}
// 确保 require 函数存在
if (typeof globalObj.require === 'undefined') {
defineGlobal('require', function(module) {
if (globalObj.__modules && globalObj.__modules[module]) {
return globalObj.__modules[module];
}
console.warn(`[RequireFallback] Module '${module}' not found`);
return {};
});
}
})();
// ====== 引擎初始化保护系统 ======
const EngineReady = (function() {
let _promise = null;
let _resolve = null;
let _isReady = false;
let _checkInterval = null;
const safeCheckEngine = () => {
// 引擎已初始化
if (cc && cc.game && cc.game._isEngineInited) {
return true;
}
// 尝试监听初始化事件
if (cc && cc.game && cc.game.once) {
const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited';
cc.game.once(eventName, () => {
_resolve && _resolve();
_isReady = true;
_checkInterval && clearInterval(_checkInterval);
});
return true;
}
return false;
};
return {
get isReady() { return _isReady; },
get promise() { return _promise; },
init() {
if (!_promise) {
_promise = new Promise(resolve => {
_resolve = () => {
_isReady = true;
resolve();
_checkInterval && clearInterval(_checkInterval);
};
// 首次检查
if (safeCheckEngine()) return;
// 轮询检查
_checkInterval = setInterval(() => {
safeCheckEngine() && _resolve();
}, 100);
});
}
return _promise;
},
safeAccess(callback) {
if (this.isReady) {
try {
const result = callback();
// 确保返回 Promise
if (result instanceof Promise) {
return result;
}
return Promise.resolve(result);
} catch (e) {
console.error('[EngineSafe] Sync error:', e);
return Promise.reject(e);
}
} else {
return this.promise.then(callback).catch(e => {
console.error('[EngineSafe] Async error:', e);
return Promise.reject(e);
});
}
}
};
})();
EngineReady.init();
// ====== 游戏主入口 ======
async function gameMainEntry() {
try {
console.log('[Main] Waiting for engine initialization...');
await EngineReady.promise;
console.log('[Main] Engine ready');
// 基本引擎配置
await EngineReady.safeAccess(() => {
if (cc.view) {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL);
}
});
// 加载SDK
await loadGravityEngineSDK();
// 加载启动场景
await loadStartScene();
} catch (error) {
console.error('[Main] Initialization failed:', error);
try {
cc.director.loadScene('start');
} catch (fallbackError) {
displayErrorFallback('启动失败\n请重启应用');
}
}
}
// 错误显示后备方案
function displayErrorFallback(message) {
try {
const errorDiv = document.createElement('div');
errorDiv.style.cssText = `
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
font: 24px Arial, sans-serif;
text-align: center;
white-space: pre-line;
padding: 20px;
`;
errorDiv.textContent = message;
document.body.appendChild(errorDiv);
} catch (e) {
console.error('[Fallback] Display failed:', e);
}
}
// ====== SDK加载器增强版 ======
async function loadGravityEngineSDK() {
// 使用相对路径解决加载问题
const sdkPaths = [
'./assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'lib/gravityengine.mg.cocoscreator.min.js'
];
for (const path of sdkPaths) {
try {
// 关键修复:在加载 SDK 前确保全局对象完整
ensureGlobalEnvironment();
// JSB 特殊处理:使用 require 加载
if (cc.sys.isNative && cc.sys.__globalAdapter?.require) {
cc.sys.__globalAdapter.require(path);
console.log('[SDK] Native require loaded:', path);
} else {
await loadScript(path);
console.log('[SDK] Loaded from:', path);
}
// 关键修复:加载后再次检查全局对象
ensureGlobalEnvironment();
initGravityEngine();
return;
} catch (e) {
console.warn('[SDK] Load failed:', path, e.message);
}
}
console.error('[SDK] All paths failed');
handleSDKLoadFailure();
}
function ensureGlobalEnvironment() {
// 获取全局对象
const getGlobalObject = () => {
if (typeof globalThis !== 'undefined') return globalThis;
if (typeof global !== 'undefined') return global;
if (typeof window !== 'undefined') return window;
if (typeof self !== 'undefined') return self;
return Function('return this')() || {};
};
const globalObj = getGlobalObject();
// 确保 self 在所有环境中都存在
if (typeof self === 'undefined') {
console.warn('[GlobalFix] self is undefined, patching...');
Object.defineProperty(globalObj, 'self', {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
// 确保其他关键全局对象存在
const requiredGlobals = ['window', 'global', 'globalThis', 'document', 'location'];
requiredGlobals.forEach(name => {
if (typeof globalObj[name] === 'undefined') {
console.warn(`[GlobalFix] ${name} is undefined, patching...`);
Object.defineProperty(globalObj, name, {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
});
// 原生平台特殊处理
if (cc && cc.sys && cc.sys.isNative) {
// 确保 location 对象存在
if (typeof location === 'undefined') {
Object.defineProperty(globalObj, 'location', {
value: {
href: 'file://',
protocol: 'file:',
hostname: 'localhost'
},
writable: false,
configurable: false,
enumerable: true
});
}
}
}
function loadScript(path) {
return new Promise((resolve, reject) => {
// 优先使用 Cocos 的加载系统
if (cc.assetManager?.loadScript) {
cc.assetManager.loadScript(path, (err) => {
if (err) {
// 原生平台特殊处理
if (cc.sys.isNative) {
console.warn('[SDK] Using native fallback for script loading');
try {
// 原生平台直接执行脚本
const jsb = cc.sys.__globalAdapter;
if (jsb && jsb.require) {
jsb.require(path);
return resolve();
}
} catch (nativeError) {
console.error('[SDK] Native require failed:', nativeError);
}
}
reject(err);
} else {
resolve();
}
});
return;
}
// 后备方案:直接创建 script 标签
try {
const script = document.createElement('script');
script.src = path;
script.onload = () => resolve();
script.onerror = () => reject(new Error(`Failed to load ${path}`));
document.head.appendChild(script);
console.warn('[SDK] Using DOM fallback for script loading');
} catch (e) {
reject(e);
}
});
}
function initGravityEngine() {
let GravityEngine = null;
// 1. 尝试从 globalThis 中查找
if (typeof globalThis.GravityEngine === 'function') {
GravityEngine = globalThis.GravityEngine;
console.log('[SDK] Found GravityEngine in globalThis');
}
// 2. 尝试从 window 对象中查找
else if (typeof window.GravityEngine === 'function') {
GravityEngine = window.GravityEngine;
console.warn('[SDK] Found GravityEngine in window object');
}
// 3. 尝试从 global 对象中查找
else if (typeof global.GravityEngine === 'function') {
GravityEngine = global.GravityEngine;
console.warn('[SDK] Found GravityEngine in global object');
}
// 4. 尝试从 self 对象中查找
else if (typeof self.GravityEngine === 'function') {
GravityEngine = self.GravityEngine;
console.warn('[SDK] Found GravityEngine in self object');
}
else {
console.error('[SDK] GravityEngine not found');
return;
}
try {
// 使用您的 AppID 624768904
GravityEngine.init({
appId: '624768904',
enableLog: true
});
console.log('[SDK] GravityEngine initialized with AppID 624768904');
} catch (e) {
console.error('[SDK] Init failed:', e);
}
}
function handleSDKLoadFailure() {
console.warn('[SDK] Using fallback analytics');
window.GravityEngine = {
init: () => console.warn('SDK unavailable'),
trackEvent: () => {}
};
}
// ====== 场景加载器 ======
async function loadStartScene() {
try {
// 加载主资源包
await new Promise((resolve) => {
if (!cc.assetManager?.loadBundle) {
console.warn('[Scene] AssetManager unavailable');
return resolve();
}
cc.assetManager.loadBundle('main', (err) => {
if (err) console.error('[Scene] Bundle load error:', err);
resolve();
});
});
// 加载场景
if (cc.director?.loadScene) {
cc.director.loadScene('start');
} else {
throw new Error('Director unavailable');
}
} catch (error) {
console.error('[Scene] Load failed:', error);
try {
cc.director.loadScene('start');
} catch (e) {
throw new Error('Fallback scene load failed');
}
}
}
// ====== UI_Entry组件 ======
const { ccclass, property } = cc._decorator;
@ccclass
export default class UI_Entry extends cc.Component {
@property(cc.ProgressBar)
progress_loading = null;
loginTimeoutHandler = null;
onLoad() {
// 修改点:使用 safeAccess 返回的 Promise 并捕获错误
EngineReady.safeAccess(() => {
try {
cc.director.getCollisionManager().enabled = true;
this._show();
} catch (e) {
console.error('[UI] onLoad error:', e);
this.startLoadGame();
// 抛出错误以便在 catch 中处理
throw e;
}
}).catch(e => {
console.error('[UI] Engine access error:', e);
this.startLoadGame();
});
}
onDestroy() {
this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler);
}
async _show() {
this.progress_loading.progress = 0;
// 平台SDK初始化
if (cc.sys.isBrowser) {
try {
await this.initYPSDK();
} catch (e) {
console.error('[YPSDK] Init failed:', e);
this.startLoadGame();
}
} else {
this.startLoadGame();
}
// 登录超时保护
this.setLoginTimeout();
}
setLoginTimeout() {
if (cc.tween) {
this.loginTimeoutHandler = cc.tween(this)
.delay(10)
.call(() => {
console.warn('[Login] Timeout after 10s');
this.startLoadGame();
})
.start();
} else {
setTimeout(() => this.startLoadGame(), 10000);
}
}
async initYPSDK() {
if (typeof YPSDK === 'undefined') {
console.warn('[YPSDK] SDK unavailable');
return;
}
const config = {
gameChannelList: {
h5: { platformType: "h5", version: "1.0.0" },
tt: { platformType: "tt", appId: "tt09297f94961f881b02" },
wx: { platformType: "wx", appId: "wx6baaaa27ab5186ff" }
}
};
await YPSDK.init(39, "https://platform-shop-dev.hanyougame.com", config);
await YPSDK.login();
if (YPSDK.setLoginCallBack) {
YPSDK.setLoginCallBack(success => {
if (!success) return;
// 取消超时
this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler);
// 初始化分析SDK
if (r_GravityPlatform.default?.GA_Init) {
r_GravityPlatform.default.GA_Init(YPSDK.Platform.loginData.bindingId);
}
this.startLoadGame();
});
} else {
this.startLoadGame();
}
}
startLoadGame() {
const tasks = [
this._loadGameConfig,
this._loadRemoteConfig,
this._loadExcelData,
this._loadUserData,
this._loadCommonBundle,
this._loadMainBundle
].map(fn => fn.bind(this));
this.executeTasks(tasks, () => this._loadGame());
}
executeTasks(tasks, finalCallback) {
let completed = 0;
const total = tasks.length;
const runTask = async (index) => {
if (index >= total) {
finalCallback();
return;
}
try {
await tasks[index]();
completed++;
this._setProgress(completed / total);
runTask(index + 1);
} catch (e) {
console.error(`[Task ${index}] Failed:`, e);
completed++;
this._setProgress(completed / total);
runTask(index + 1); // 继续执行后续任务
}
};
runTask(0);
}
async _loadExcelData() {
if (!r_ExcelLoader?.ExcelLoader?.loadAll) {
console.warn('[Data] ExcelLoader unavailable');
return;
}
await r_ExcelLoader.ExcelLoader.loadAll();
console.log('[Data] Excel loaded');
}
async _loadGameConfig() {
if (!r_ResLoader.default?.loadRes) {
console.warn('[Config] ResLoader unavailable');
return;
}
const jsonAsset = await r_ResLoader.default.loadRes(
"resources",
"config/GameConfig",
cc.JsonAsset
);
if (jsonAsset && r_GameConfig.default) {
r_GameConfig.default.appConfig = jsonAsset.json;
jsonAsset.decRef && jsonAsset.decRef();
console.log('[Config] Game config loaded');
}
}
async _loadRemoteConfig() {
if (!r_GameConfig.default?.appConfig?.RemoteUrl) {
console.warn('[Config] RemoteUrl not set');
return;
}
const remoteUrl = r_GameConfig.default.appConfig.RemoteUrl;
const remotePath = cc.path.join(remoteUrl, "ADConfig.json");
try {
const remoteConfig = await r_ResLoader.default.loadRemote(remotePath, { ext: ".json" });
if (remoteConfig?.json && r_GravityPlatform.default) {
r_GravityPlatform.default.videoId = remoteConfig.json.ADUnitId[0];
r_GameConfig.default.adConfig = remoteConfig.json;
console.log('[Config] Remote config loaded');
}
} catch (e) {
console.error('[Config] Remote load failed:', e);
}
}
async _loadCommonBundle() {
if (!r_ResLoader.default?.loadBundle) {
console.warn('[Bundle] ResLoader unavailable');
return;
}
try {
await r_ResLoader.default.loadBundle(r_BundleConfig.BundleNames.Common);
console.log('[Bundle] Common loaded');
} catch (e) {
console.error('[Bundle] Common load failed:', e);
}
}
async _loadMainBundle() {
if (!r_ResLoader.default?.loadBundle) {
console.warn('[Bundle] ResLoader unavailable');
return;
}
try {
await r_ResLoader.default.loadBundle(r_BundleConfig.MainGameBundle);
console.log('[Bundle] Main loaded');
} catch (e) {
console.error('[Bundle] Main load failed:', e);
}
}
async _loadUserData() {
try {
// 音频初始化
r_AudioManager.AudioMgr?.init();
// 全局配置
r_GameGlobalVariable.GameGlobalVariable?.initPeiZhi();
// 网络检测
if (YPSDK?.Common?.curChannelData) {
const platformType = YPSDK.Common.curChannelData.platformType;
if (platformType === YPSDK.GamePlatformType.WX || platformType === YPSDK.GamePlatformType.TT) {
r_YpNetMag.YpNetMag?.failSever(() => {
r_YpNetMag.YpNetMag.isFail = true;
});
}
}
// 用户数据初始化
if (YPSDK?.Platform?.loginData) {
await r_YpNetMag.YpNetMag?.initServer(YPSDK.Platform.loginData);
}
} catch (e) {
console.error('[User] Load failed:', e);
}
}
_loadGame() {
try {
const guideIndex = r_PlayerDataManager.PlayerDataMgr.GetGuideIndexByTaskName(
r_Const_Common.GuideName.战斗背包
);
if (guideIndex !== r_Const_Common.GameBagGuideIndex.引导完结) {
// 新玩家流程
r_PlayerDataManager.PlayerDataMgr.GMSetGuideIndex?.(
r_Const_Common.GuideName.战斗背包,
r_Const_Common.GameBagGuideIndex.引导初始1
);
r_GameDataManager.GameDataMgr?.ClearGameBagData();
r_GameGlobalVariable.GameGlobalVariable.nowlevel = 1;
r_UIManager.default?.open(
r_BundleConfig.BundleNames.Game,
r_UIConfig_Game.UIView_Game.UI_GameView
);
} else {
// 老玩家流程
r_EventManager.EventMgr?.dispatchEvent(r_EvenType.EVENT_TYPE.Game_Load_View, true);
r_UIManager.default?.open(
r_BundleConfig.BundleNames.Home,
r_UIConfig_Home.UIView_Home.UI_Hall
);
}
// 白名单检查
this.checkWhiteList();
} catch (e) {
console.error('[Game] Load failed:', e);
try {
cc.director.loadScene('start');
} catch (sceneError) {
console.error('[Game] Scene load failed:', sceneError);
}
}
}
async checkWhiteList() {
try {
if (!YPSDK?.Platform?.loginData || !YPSDK.platformUrl) return;
const url = `${YPSDK.platformUrl}/User/GetCfgData?userId=${YPSDK.Platform.loginData.userUid}&keyId=NoVideo`;
if (r_HttpManager.HttpMgr?.requestData) {
r_HttpManager.HttpMgr.requestData(res => {
if (res?.data?.keyData === "true") {
r_PlayerDataManager.PlayerDataMgr.WHITE_NAME_NO_VIDEO = true;
}
}, url);
}
} catch (e) {
console.error('[WhiteList] Check failed:', e);
}
}
_setProgress(progress) {
if (!this.progress_loading) return;
this.progress_loading.progress = Math.max(0, Math.min(1, progress));
}
}
// ====== 启动游戏 ======
if (cc?.game?.run) {
cc.game.run(() => {
// 确保环境修复完成
ensureGlobalEnvironment();
gameMainEntry();
});
} else {
setTimeout(() => {
ensureGlobalEnvironment();
gameMainEntry();
}, 1000);
}
```
### 注意事项
1. 这个修改版本解决了 `Cannot read property 'catch' of undefined` 错误,因为现在 `EngineReady.safeAccess` 总是返回一个 Promise。
2. 增强了全局环境修复,特别是在加载 SDK 前后。
3. 优化了 GravityEngine SDK 的加载和初始化。
请将这段完整代码替换到您的项目中,并测试运行。如果问题仍然存在,请检查控制台日志以获取更多线索。
§§相关问题§§:
1. 在 Cocos Creator 中,如何处理多平台(H5、微信小游戏、原生应用)的全局对象差异?
2. 如何优化 Cocos Creator 项目的启动时间,特别是资源加载和 SDK 初始化?
3. 在 JavaScript 中,如何设计一个健壮的错误处理机制来捕获异步和同步错误?
4. 如何实现 Cocos Creator 项目的热更新,特别是在原生平台?</think>以下是针对您的问题修改后的完整代码。主要修复了 `EngineReady.safeAccess()` 的 Promise 处理逻辑,确保在所有情况下都返回 Promise,并增强了全局环境修复功能:
```javascript
// ====== 环境修复与全局对象安全 ======
(function() {
// 安全获取全局对象的函数(支持严格模式和所有环境)
const getGlobalObject = () => {
// 1. 优先使用现代标准 globalThis
if (typeof globalThis !== 'undefined') return globalThis;
// 2. 处理严格模式限制
try {
const globalFromFn = Function('return this')();
if (globalFromFn) return globalFromFn;
} catch (e) {
console.warn('[EnvFix] Function constructor blocked in strict mode');
}
// 3. 环境特定对象
if (typeof global !== 'undefined') return global; // Node.js
if (typeof window !== 'undefined') return window; // 浏览器
if (typeof self !== 'undefined') return self; // Web Worker
// 4. Cocos Creator 原生环境特殊处理
if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) {
return cc.sys.__globalAdapter;
}
// 5. 最后手段:创建新的全局对象
console.error('[EnvFix] Unable to determine global object, creating new');
return {};
};
const globalObj = getGlobalObject();
// 修复关键全局变量(使用 Object.defineProperty 防止覆盖)
const defineGlobal = (name, value) => {
if (typeof globalObj[name] === 'undefined') {
Object.defineProperty(globalObj, name, {
value,
writable: true,
configurable: true,
enumerable: true
});
console.log(`[EnvFix] Defined global: ${name}`);
}
};
// 定义关键全局对象
defineGlobal('global', globalObj);
defineGlobal('self', globalObj);
defineGlobal('globalThis', globalObj);
defineGlobal('window', globalObj);
// 原生平台特殊处理
if (cc && cc.sys && cc.sys.isNative) {
// 确保 XMLHttpRequest 存在
if (typeof XMLHttpRequest === 'undefined') {
defineGlobal('XMLHttpRequest', function() {
return cc.loader.getXMLHttpRequest();
});
}
// 确保 document 对象存在
if (typeof document === 'undefined') {
defineGlobal('document', {
createElement: () => ({ appendChild: () => {} }),
head: { appendChild: () => {} },
body: { appendChild: () => {} }
});
}
// 确保 location 对象存在
if (typeof location === 'undefined') {
defineGlobal('location', {
href: 'file://',
protocol: 'file:',
hostname: 'localhost',
host: 'localhost',
origin: 'file://'
});
}
console.log('[EnvFix] Native environment patched');
}
// 确保 require 函数存在
if (typeof globalObj.require === 'undefined') {
defineGlobal('require', function(module) {
if (globalObj.__modules && globalObj.__modules[module]) {
return globalObj.__modules[module];
}
console.warn(`[RequireFallback] Module '${module}' not found`);
return {};
});
}
})();
// ====== 引擎初始化保护系统 ======
const EngineReady = (function() {
let _promise = null;
let _resolve = null;
let _isReady = false;
let _checkInterval = null;
const safeCheckEngine = () => {
// 引擎已初始化
if (cc && cc.game && cc.game._isEngineInited) {
return true;
}
// 尝试监听初始化事件
if (cc && cc.game && cc.game.once) {
const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited';
cc.game.once(eventName, () => {
_resolve && _resolve();
_isReady = true;
_checkInterval && clearInterval(_checkInterval);
});
return true;
}
return false;
};
return {
get isReady() { return _isReady; },
get promise() { return _promise; },
init() {
if (!_promise) {
_promise = new Promise(resolve => {
_resolve = () => {
_isReady = true;
resolve();
_checkInterval && clearInterval(_checkInterval);
};
// 首次检查
if (safeCheckEngine()) return;
// 轮询检查
_checkInterval = setInterval(() => {
safeCheckEngine() && _resolve();
}, 100);
});
}
return _promise;
},
safeAccess(callback) {
if (this.isReady) {
try {
const result = callback();
// 确保返回 Promise
if (result instanceof Promise) {
return result;
}
return Promise.resolve(result);
} catch (e) {
console.error('[EngineSafe] Sync error:', e);
return Promise.reject(e);
}
} else {
return this.promise.then(callback).catch(e => {
console.error('[EngineSafe] Async error:', e);
return Promise.reject(e);
});
}
}
};
})();
EngineReady.init();
// ====== 游戏主入口 ======
async function gameMainEntry() {
try {
console.log('[Main] Waiting for engine initialization...');
await EngineReady.promise;
console.log('[Main] Engine ready');
// 基本引擎配置
await EngineReady.safeAccess(() => {
if (cc.view) {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL);
}
});
// 加载SDK
await loadGravityEngineSDK();
// 加载启动场景
await loadStartScene();
} catch (error) {
console.error('[Main] Initialization failed:', error);
try {
cc.director.loadScene('start');
} catch (fallbackError) {
displayErrorFallback('启动失败\n请重启应用');
}
}
}
// 错误显示后备方案
function displayErrorFallback(message) {
try {
const errorDiv = document.createElement('div');
errorDiv.style.cssText = `
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
font: 24px Arial, sans-serif;
text-align: center;
white-space: pre-line;
padding: 20px;
`;
errorDiv.textContent = message;
document.body.appendChild(errorDiv);
} catch (e) {
console.error('[Fallback] Display failed:', e);
}
}
// ====== SDK加载器增强版 ======
async function loadGravityEngineSDK() {
// 使用相对路径解决加载问题
const sdkPaths = [
'./assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'lib/gravityengine.mg.cocoscreator.min.js'
];
for (const path of sdkPaths) {
try {
// 关键修复:在加载 SDK 前确保全局对象完整
ensureGlobalEnvironment();
// JSB 特殊处理:使用 require 加载
if (cc.sys.isNative && cc.sys.__globalAdapter?.require) {
cc.sys.__globalAdapter.require(path);
console.log('[SDK] Native require loaded:', path);
} else {
await loadScript(path);
console.log('[SDK] Loaded from:', path);
}
// 关键修复:加载后再次检查全局对象
ensureGlobalEnvironment();
initGravityEngine();
return;
} catch (e) {
console.warn('[SDK] Load failed:', path, e.message);
}
}
console.error('[SDK] All paths failed');
handleSDKLoadFailure();
}
function ensureGlobalEnvironment() {
// 获取全局对象
const getGlobalObject = () => {
if (typeof globalThis !== 'undefined') return globalThis;
if (typeof global !== 'undefined') return global;
if (typeof window !== 'undefined') return window;
if (typeof self !== 'undefined') return self;
return Function('return this')() || {};
};
const globalObj = getGlobalObject();
// 确保 self 在所有环境中都存在
if (typeof self === 'undefined') {
console.warn('[GlobalFix] self is undefined, patching...');
Object.defineProperty(globalObj, 'self', {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
// 确保其他关键全局对象存在
const requiredGlobals = ['window', 'global', 'globalThis', 'document', 'location'];
requiredGlobals.forEach(name => {
if (typeof globalObj[name] === 'undefined') {
console.warn(`[GlobalFix] ${name} is undefined, patching...`);
Object.defineProperty(globalObj, name, {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
});
// 原生平台特殊处理
if (cc && cc.sys && cc.sys.isNative) {
// 确保 location 对象存在
if (typeof location === 'undefined') {
Object.defineProperty(globalObj, 'location', {
value: {
href: 'file://',
protocol: 'file:',
hostname: 'localhost'
},
writable: false,
configurable: false,
enumerable: true
});
}
}
}
function loadScript(path) {
return new Promise((resolve, reject) => {
// 优先使用 Cocos 的加载系统
if (cc.assetManager?.loadScript) {
cc.assetManager.loadScript(path, (err) => {
if (err) {
// 原生平台特殊处理
if (cc.sys.isNative) {
console.warn('[SDK] Using native fallback for script loading');
try {
// 原生平台直接执行脚本
const jsb = cc.sys.__globalAdapter;
if (jsb && jsb.require) {
jsb.require(path);
return resolve();
}
} catch (nativeError) {
console.error('[SDK] Native require failed:', nativeError);
}
}
reject(err);
} else {
resolve();
}
});
return;
}
// 后备方案:直接创建 script 标签
try {
const script = document.createElement('script');
script.src = path;
script.onload = () => resolve();
script.onerror = () => reject(new Error(`Failed to load ${path}`));
document.head.appendChild(script);
console.warn('[SDK] Using DOM fallback for script loading');
} catch (e) {
reject(e);
}
});
}
function initGravityEngine() {
let GravityEngine = null;
// 1. 尝试从 globalThis 中查找
if (typeof globalThis.GravityEngine === 'function') {
GravityEngine = globalThis.GravityEngine;
console.log('[SDK] Found GravityEngine in globalThis');
}
// 2. 尝试从 window 对象中查找
else if (typeof window.GravityEngine === 'function') {
GravityEngine = window.GravityEngine;
console.warn('[SDK] Found GravityEngine in window object');
}
// 3. 尝试从 global 对象中查找
else if (typeof global.GravityEngine === 'function') {
GravityEngine = global.GravityEngine;
console.warn('[SDK] Found GravityEngine in global object');
}
// 4. 尝试从 self 对象中查找
else if (typeof self.GravityEngine === 'function') {
GravityEngine = self.GravityEngine;
console.warn('[SDK] Found GravityEngine in self object');
}
else {
console.error('[SDK] GravityEngine not found');
return;
}
try {
// 使用您的 AppID 624768904
GravityEngine.init({
appId: '624768904',
enableLog: true
});
console.log('[SDK] GravityEngine initialized with AppID 624768904');
} catch (e) {
console.error('[SDK] Init failed:', e);
}
}
function handleSDKLoadFailure() {
console.warn('[SDK] Using fallback analytics');
window.GravityEngine = {
init: () => console.warn('SDK unavailable'),
trackEvent: () => {}
};
}
// ====== 场景加载器 ======
async function loadStartScene() {
try {
// 加载主资源包
await new Promise((resolve) => {
if (!cc.assetManager?.loadBundle) {
console.warn('[Scene] AssetManager unavailable');
return resolve();
}
cc.assetManager.loadBundle('main', (err) => {
if (err) console.error('[Scene] Bundle load error:', err);
resolve();
});
});
// 加载场景
if (cc.director?.loadScene) {
cc.director.loadScene('start');
} else {
throw new Error('Director unavailable');
}
} catch (error) {
console.error('[Scene] Load failed:', error);
try {
cc.director.loadScene('start');
} catch (e) {
throw new Error('Fallback scene load failed');
}
}
}
// ====== UI_Entry组件 ======
const { ccclass, property } = cc._decorator;
@ccclass
export default class UI_Entry extends cc.Component {
@property(cc.ProgressBar)
progress_loading = null;
loginTimeoutHandler = null;
onLoad() {
// 修改点:使用 safeAccess 返回的 Promise 并捕获错误
EngineReady.safeAccess(() => {
try {
cc.director.getCollisionManager().enabled = true;
this._show();
} catch (e) {
console.error('[UI] onLoad error:', e);
this.startLoadGame();
// 抛出错误以便在 catch 中处理
throw e;
}
}).catch(e => {
// 这里捕获到错误(包括同步路径中抛出的错误)
console.error('[UI] Engine access error:', e);
this.startLoadGame();
});
}
onDestroy() {
this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler);
}
async _show() {
this.progress_loading.progress = 0;
// 平台SDK初始化
if (cc.sys.isBrowser) {
try {
await this.initYPSDK();
} catch (e) {
console.error('[YPSDK] Init failed:', e);
this.startLoadGame();
}
} else {
this.startLoadGame();
}
// 登录超时保护
this.setLoginTimeout();
}
setLoginTimeout() {
if (cc.tween) {
this.loginTimeoutHandler = cc.tween(this)
.delay(10)
.call(() => {
console.warn('[Login] Timeout after 10s');
this.startLoadGame();
})
.start();
} else {
setTimeout(() => this.startLoadGame(), 10000);
}
}
async initYPSDK() {
if (typeof YPSDK === 'undefined') {
console.warn('[YPSDK] SDK unavailable');
return;
}
const config = {
gameChannelList: {
h5: { platformType: "h5", version: "1.0.0" },
tt: { platformType: "tt", appId: "tt09297f94961f881b02" },
wx: { platformType: "wx", appId: "wx6baaaa27ab5186ff" }
}
};
await YPSDK.init(39, "https://platform-shop-dev.hanyougame.com", config);
await YPSDK.login();
if (YPSDK.setLoginCallBack) {
YPSDK.setLoginCallBack(success => {
if (!success) return;
// 取消超时
this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler);
// 初始化分析SDK
if (r_GravityPlatform.default?.GA_Init) {
r_GravityPlatform.default.GA_Init(YPSDK.Platform.loginData.bindingId);
}
this.startLoadGame();
});
} else {
this.startLoadGame();
}
}
startLoadGame() {
const tasks = [
this._loadGameConfig,
this._loadRemoteConfig,
this._loadExcelData,
this._loadUserData,
this._loadCommonBundle,
this._loadMainBundle
].map(fn => fn.bind(this));
this.executeTasks(tasks, () => this._loadGame());
}
executeTasks(tasks, finalCallback) {
let completed = 0;
const total = tasks.length;
const runTask = async (index) => {
if (index >= total) {
finalCallback();
return;
}
try {
await tasks[index]();
completed++;
this._setProgress(completed / total);
runTask(index + 1);
} catch (e) {
console.error(`[Task ${index}] Failed:`, e);
completed++;
this._setProgress(completed / total);
runTask(index + 1); // 继续执行后续任务
}
};
runTask(0);
}
async _loadExcelData() {
if (!r_ExcelLoader?.ExcelLoader?.loadAll) {
console.warn('[Data] ExcelLoader unavailable');
return;
}
await r_ExcelLoader.ExcelLoader.loadAll();
console.log('[Data] Excel loaded');
}
async _loadGameConfig() {
if (!r_ResLoader.default?.loadRes) {
console.warn('[Config] ResLoader unavailable');
return;
}
const jsonAsset = await r_ResLoader.default.loadRes(
"resources",
"config/GameConfig",
cc.JsonAsset
);
if (jsonAsset && r_GameConfig.default) {
r_GameConfig.default.appConfig = jsonAsset.json;
jsonAsset.decRef && jsonAsset.decRef();
console.log('[Config] Game config loaded');
}
}
async _loadRemoteConfig() {
if (!r_GameConfig.default?.appConfig?.RemoteUrl) {
console.warn '[Config] RemoteUrl not set');
return;
}
const remoteUrl = r_GameConfig.default.appConfig.RemoteUrl;
const remotePath = cc.path.join(remoteUrl, "ADConfig.json");
try {
const remoteConfig = await r_ResLoader.default.loadRemote(remotePath, { ext: ".json" });
if (remoteConfig?.json && r_GravityPlatform.default) {
r_GravityPlatform.default.videoId = remoteConfig.json.ADUnitId[0];
r_GameConfig.default.adConfig = remoteConfig.json;
console.log('[Config] Remote config loaded');
}
} catch (e) {
console.error('[Config] Remote load failed:', e);
}
}
async _loadCommonBundle() {
if (!r_ResLoader.default?.loadBundle) {
console.warn('[Bundle] ResLoader unavailable');
return;
}
try {
await r_ResLoader.default.loadBundle(r_BundleConfig.BundleNames.Common);
console.log('[Bundle] Common loaded');
} catch (e) {
console.error('[Bundle] Common load failed:', e);
}
}
async _loadMainBundle() {
if (!r_ResLoader.default?.loadBundle) {
console.warn('[Bundle] ResLoader unavailable');
return;
}
try {
await r_ResLoader.default.loadBundle(r_BundleConfig.MainGameBundle);
console.log('[Bundle] Main loaded');
} catch (e) {
console.error('[Bundle] Main load failed:', e);
}
}
async _loadUserData() {
try {
// 音频初始化
r_AudioManager.AudioMgr?.init();
// 全局配置
r_GameGlobalVariable.GameGlobalVariable?.initPeiZhi();
// 网络检测
if (YPSDK?.Common?.curChannelData) {
const platformType = YPSDK.Common.curChannelData.platformType;
if (platformType === YPSDK.GamePlatformType.WX || platformType === YPSDK.GamePlatformType.TT) {
r_YpNetMag.YpNetMag?.failSever(() => {
r_YpNetMag.YpNetMag.isFail = true;
});
}
}
// 用户数据初始化
if (YPSDK?.Platform?.loginData) {
await r_YpNetMag.YpNetMag?.initServer(YPSDK.Platform.loginData);
}
} catch (e) {
console.error('[User] Load failed:', e);
}
}
_loadGame() {
try {
const guideIndex = r_PlayerDataManager.PlayerDataMgr.GetGuideIndexByTaskName(
r_Const_Common.GuideName.战斗背包
);
if (guideIndex !== r_Const_Common.GameBagGuideIndex.引导完结) {
// 新玩家流程
r_PlayerDataManager.PlayerDataMgr.GMSetGuideIndex?.(
r_Const_Common.GuideName.战斗背包,
r_Const_Common.GameBagGuideIndex.引导初始1
);
r_GameDataManager.GameDataMgr?.ClearGameBagData();
r_GameGlobalVariable.GameGlobalVariable.nowlevel = 1;
r_UIManager.default?.open(
r_BundleConfig.BundleNames.Game,
r_UIConfig_Game.UIView_Game.UI_GameView
);
} else {
// 老玩家流程
r_EventManager.EventMgr?.dispatchEvent(r_EvenType.EVENT_TYPE.Game_Load_View, true);
r_UIManager.default?.open(
r_BundleConfig.BundleNames.Home,
r_UIConfig_Home.UIView_Home.UI_Hall
);
}
// 白名单检查
this.checkWhiteList();
} catch (e) {
console.error('[Game] Load failed:', e);
try {
cc.director.loadScene('start');
} catch (sceneError) {
console.error('[Game] Scene load failed:', sceneError);
}
}
}
async checkWhiteList() {
try {
if (!YPSDK?.Platform?.loginData || !YPSDK.platformUrl) return;
const url = `${YPSDK.platformUrl}/User/GetCfgData?userId=${YPSDK.Platform.loginData.userUid}&keyId=NoVideo`;
if (r_HttpManager.HttpMgr?.requestData) {
r_HttpManager.HttpMgr.requestData(res => {
if (res?.data?.keyData === "true") {
r_PlayerDataManager.PlayerDataMgr.WHITE_NAME_NO_VIDEO = true;
}
}, url);
}
} catch (e) {
console.error('[WhiteList] Check failed:', e);
}
}
_setProgress(progress) {
if (!this.progress_loading) return;
this.progress_loading.progress = Math.max(0, Math.min(1, progress));
}
}
// ====== 启动游戏 ======
if (cc?.game?.run) {
cc.game.run(() => {
// 确保环境修复完成
ensureGlobalEnvironment();
gameMainEntry();
});
} else {
setTimeout(() => {
ensureGlobalEnvironment();
gameMainEntry();
}, 1000);
}
```
### 关键修改说明
1. **`EngineReady.safeAccess` 方法修复**:
```javascript
safeAccess(callback) {
if (this.isReady) {
try {
const result = callback();
// 确保返回 Promise
if (result instanceof Promise) {
return result;
}
return Promise.resolve(result);
} catch (e) {
console.error('[EngineSafe] Sync error:', e);
return Promise.reject(e);
}
} else {
return this.promise.then(callback).catch(e => {
console.error('[EngineSafe] Async error:', e);
return Promise.reject(e);
});
}
}
```
- 现在始终返回 Promise,无论引擎是否就绪
- 同步执行路径中,如果回调返回非 Promise 值,会使用 `Promise.resolve()` 包装
- 同步执行路径中的错误会被捕获并返回 `Promise.reject()`
2. **`UI_Entry.onLoad` 方法修复**:
```javascript
onLoad() {
EngineReady.safeAccess(() => {
try {
cc.director.getCollisionManager().enabled = true;
this._show();
} catch (e) {
console.error('[UI] onLoad error:', e);
this.startLoadGame();
// 抛出错误以便在 catch 中处理
throw e;
}
}).catch(e => {
// 这里捕获到错误(包括同步路径中抛出的错误)
console.error('[UI] Engine access error:', e);
this.startLoadGame();
});
}
```
- 使用 `.catch()` 统一处理所有错误路径
- 在同步错误中重新抛出错误,确保能被 `.catch()` 捕获
3. **全局环境修复增强**:
```javascript
function ensureGlobalEnvironment() {
// ... 获取全局对象 ...
// 确保 self 在所有环境中都存在
if (typeof self === 'undefined') {
Object.defineProperty(globalObj, 'self', {
value: globalObj,
writable: true,
configurable: true,
enumerable: true
});
}
// ... 其他全局对象修复 ...
}
```
- 特别确保 `self` 被定义为全局对象
- 在 SDK 加载前后都调用此函数
4. **GravityEngine 初始化优化**:
```javascript
function initGravityEngine() {
let GravityEngine = null;
// 1. 尝试从 globalThis 中查找
if (typeof globalThis.GravityEngine === 'function') {
GravityEngine = globalThis.GravityEngine;
console.log('[SDK] Found GravityEngine in globalThis');
}
// 2. 尝试从 window 对象中查找
else if (typeof window.GravityEngine === 'function') {
GravityEngine = window.GravityEngine;
console.warn('[SDK] Found GravityEngine in window object');
}
// ... 其他查找路径 ...
}
```
- 优先检查 `globalThis` 对象
- 添加更详细的日志输出
5. **游戏主入口优化**:
```javascript
async function gameMainEntry() {
try {
// ... 等待引擎初始化 ...
// 基本引擎配置
await EngineReady.safeAccess(() => {
// ... 配置代码 ...
});
// ... 其他初始化 ...
} catch (error) {
// ... 错误处理 ...
}
}
```
- 使用 `await` 等待 `EngineReady.safeAccess()` 完成
- 添加更健壮的错误处理
### 测试建议
1. **测试环境**:
- 在 Web 浏览器、微信小游戏、原生平台(Android/iOS)分别测试
- 测试不同网络条件下的加载情况
2. **验证点**:
- 确保不再出现 `Cannot read property 'catch' of undefined` 错误
- 验证 SDK 在所有平台上都能正确加载和初始化
- 检查全局对象(self、window 等)在所有环境中都正确存在
3. **错误日志**:
- 在关键位置添加详细日志:
```javascript
console.log('[DEBUG] EngineReady status:', {
isReady: EngineReady.isReady,
promise: EngineReady.promise
});
```