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

p5.js中能否预加载配置JSON内指定的其他JSON文件?

在p5.js中预加载配置文件引用的嵌套JSON文件

这个问题确实是p5.js预加载机制里的典型痛点——preload()是同步阻塞的,但它只能执行一次,没法直接嵌套加载依赖的文件。不过有两种靠谱的解决思路,我帮你拆解清楚:

方案1:用loadJSON的异步回调实现二次加载

p5.js的loadJSON支持传入成功回调函数,你可以在setup()里先拿到预加载好的主配置,然后遍历每个歌曲对象,用带回调的loadJSON加载对应的子JSON,再通过计数器判断是否全部加载完成,之后再启动核心逻辑。

示例代码:

let config;
let songData = [];
let loadedCount = 0;

function preload() {
  // 先预加载主配置文件
  config = loadJSON('config.json');
}

function setup() {
  createCanvas(800, 600);
  
  // 从配置中取出歌曲列表
  const songs = config.songs;
  songs.forEach((song, index) => {
    // 为每个歌曲文件绑定加载回调
    loadJSON(song.filename, (data) => {
      songData[index] = data;
      loadedCount++;
      
      // 所有子文件加载完成后,触发初始化
      if (loadedCount === songs.length) {
        initApp();
      }
    }, (error) => {
      // 可选:处理加载失败的情况
      console.error(`加载${song.filename}失败:`, error);
      loadedCount++;
    });
  });
}

function initApp() {
  // 这里可以安全地使用config和songData了
  console.log('所有数据加载完成!');
  console.log('配置信息:', config);
  console.log('歌曲详情:', songData);
}

function draw() {
  // 加载完成前显示加载提示
  if (loadedCount < config?.songs?.length) {
    background(200);
    textSize(16);
    textAlign(CENTER, CENTER);
    text('加载中,请稍候...', width/2, height/2);
  } else {
    // 正常绘制逻辑
    background(255);
    // 比如显示歌曲名称
    text(songData[0].songName, 50, 50);
  }
}

方案2:用Promise封装加载流程(更优雅的异步管理)

如果你的项目逻辑比较复杂,用Promise来管理所有加载任务会更清晰,还能借助Promise.all()一次性等待所有子文件加载完成,代码结构更整洁。

示例代码:

let config;
let songData = [];

function preload() {
  config = loadJSON('config.json');
}

function setup() {
  createCanvas(800, 600);
  
  // 把每个loadJSON调用包装成Promise
  const loadPromises = config.songs.map(song => {
    return new Promise((resolve, reject) => {
      loadJSON(song.filename, resolve, reject);
    });
  });
  
  // 等待所有Promise完成
  Promise.all(loadPromises)
    .then(dataArray => {
      songData = dataArray;
      initApp();
    })
    .catch(error => {
      console.error('加载子文件出错:', error);
    });
}

function initApp() {
  console.log('全部数据加载完成,启动应用');
  // 在这里编写核心业务逻辑
}

function draw() {
  if (!songData.length) {
    background(200);
    textSize(16);
    textAlign(CENTER, CENTER);
    text('加载中...', width/2, height/2);
  } else {
    background(255);
    // 正常绘制内容
  }
}

关键注意点

  • 子JSON文件的路径是相对于HTML文件的位置,而不是主配置文件的位置,别搞错路径导致加载失败。
  • 可以在loadJSON的第三个参数中添加错误回调,处理文件找不到、网络异常等情况,避免程序卡住。
  • 绝对不要在draw()里执行加载操作,否则会每帧都触发加载请求,一定要把加载逻辑放在setup()或初始化函数中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:54:21