JS用async/await配合fetch读取JSON失效,无法实现PHP include效果如何解决
问题成因
- 服务端嵌入逻辑差异:PHP版本是在服务端页面渲染阶段,直接把JSON文件内容作为JS对象字面量嵌入到输出的JS代码中,属于静态赋值,不存在异步加载的时序问题,所以可以直接拿到正常数据。
- 异步时序问题:fetch是异步网络请求,async函数执行时不会阻塞后续代码运行,如果你调用
cccrFlow()之后立刻同步访问club_mems,此时请求还未返回,数据还没完成赋值,自然拿不到预期结果,这是这类问题最常见的诱因。 - 代码不规范问题:原JS代码里的
response、club_mems都没有用let/const声明,容易产生作用域污染、变量覆盖的问题,可能会干扰正常赋值。 - 缺少错误校验:fetch只有在网络完全中断的情况下才会抛出错误,哪怕请求返回404、500等异常状态码也会正常返回响应对象,原代码没有判断请求是否成功,一旦出现路径错误、跨域等问题导致返回非JSON内容,调用
response.json()就会直接报错。 - 路径/协议限制问题:fetch的请求路径是相对于当前打开的HTML页面路径,而非JS文件本身的路径,容易出现路径写错导致404的情况;如果是本地直接通过
file://协议打开HTML文件测试,浏览器的同源策略也会禁止fetch读取本地文件,导致请求失败。
修正后的实现方案
首先调整函数逻辑,增加错误处理、规范变量声明,同时通过返回Promise的方式让调用方可以准确拿到异步返回的数据:
async function cccrFlow() { try { const response = await fetch('assets/club_mems.json'); // 先校验请求是否成功 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } const club_mems = await response.json(); // 这里可以直接写处理club_mems的业务逻辑,或者将数据return出去 console.log('读取到的成员数据:', club_mems); return club_mems; } catch (err) { console.error('读取JSON文件出错:', err); } }
调用时必须遵循异步逻辑,不能同步取值,两种正确调用方式如下:
- 在其他async函数中通过await调用
async function runBusiness() { const club_mems = await cccrFlow(); if (club_mems) { // 在这里写使用club_mems的业务逻辑 } } runBusiness();
- 通过.then()回调获取结果
cccrFlow().then(club_mems => { if (club_mems) { // 在这里写使用club_mems的业务逻辑 } })
额外注意
本地测试时请不要直接打开HTML文件,建议使用VS Code的Live Server插件、或者npx serve、php -S localhost:端口号等方式启动本地静态服务,通过http://localhost地址访问页面即可避免跨域限制。
内容的提问来源于stack exchange,提问作者verlager
相关产品推荐
相关产品推荐

