Skip to content

活动补单回调未执行导致进度卡住

问题描述

在 ResourceManV2 架构重构后,活动补单(lag-load activities)下载完成后,回调函数始终未被执行,导致:

  • 下载进度卡在某个百分比
  • LAGLOAD_ACTIVITY_DOWNLOAD_ENDED 事件未触发
  • 后续业务逻辑无法正常执行

根本原因

时序问题(Timing Issue):ActivityLoader 在错误的时机修改了 config.onComplete 回调。

错误的执行顺序

javascript
// ❌ 错误顺序(原代码)
var taskConfigs = this.buildTasks(activities);          // 1. 创建任务配置
var taskIds = this._addTasks(taskConfigs);              // 2. 创建 DownloadTask(此时使用旧的 onComplete)
taskConfigs.forEach(function(config) {                  // 3. 现在才修改 onComplete(太晚了!)
    config.onComplete = function(error) { ... };
});

问题:当 _addTasks() 调用时,DownloadTask 已经创建并保存了 config.onComplete 的引用。之后再修改 config.onComplete 不会影响已创建的 task。

调用链分析

  1. ActivityLoader.js:95 - 修改 config.onComplete
  2. BaseLoader.js:166-177 - _addTask 创建 DownloadTask
  3. DownloadTask - 构造函数保存 onComplete 引用
  4. DownloadQueue.js:463-539 - onTaskComplete 调用 task.onComplete

由于时序错误,第 4 步调用的是旧的 config.onComplete(buildTasks 创建的),而不是第 1 步修改后的新回调。

解决方案

_addTasks() 之前修改 config.onComplete

javascript
// ✅ 正确顺序(修复后)
var taskConfigs = this.buildTasks(activities);          // 1. 创建任务配置

taskConfigs.forEach(function(config) {                  // 2. 先修改 onComplete
    var originalCallback = config.onComplete;
    config.onComplete = function(error) {
        // 新的回调逻辑
        originalCallback && originalCallback(error);
        // ...
    };
});

var taskIds = this._addTasks(taskConfigs);              // 3. 创建 DownloadTask(使用新的 onComplete)

修复文件

影响范围

  • ActivityLoader(活动资源加载)
  • 所有依赖活动补单回调的业务逻辑
  • 进度条更新
  • 活动激活流程

验证方法

  1. 触发活动补单下载
  2. 观察控制台日志:
    [ResourceManV2][ActivityLoader] Activity download complete: activity/xxx null
  3. 确认事件触发:
    • ACTIVITY_FODLER_ONE_DOWNLOAD_FINISH
    • ACTIVITY_FODLER_ALL_DOWNLOAD_FINISH
    • LAGLOAD_ACTIVITY_DOWNLOAD_ENDED

相关问题

经验教训

  1. JavaScript 对象引用传递:修改对象属性时,要注意引用传递的时机
  2. 回调设置时机:在创建任务前设置好所有回调,避免时序问题
  3. 调试技巧:使用 cc.warn 添加关键节点日志,快速定位回调执行情况

创建日期: 2025-11-23 解决日期: 2025-11-23 相关分支: classic_vegas_cvs_v865_res_optimize

Released under the MIT License.