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

JS全局变量cleanup返回undefined 异步调用问题排查

问题背景

调试网页端脚本过程中,其余功能均已验证可用,目前遇到全局变量始终返回undefined的问题,无法判定是变量跨作用域传递失败,还是异步执行时序问题导致,暂不清楚时序问题的修复方案。

原始代码
function csvConvert(data) {
    //Data is usable here
    console.table(data);
    results = data.map(element => ({id: element.id}))

    string = JSON.stringify(results);

    window.cleanup = string.replace(/[&\/\\#+()$~%.'":*?<>{}]/g, '').replace(/id/g, '').replace(/null/g, '').slice(0, -2).substring(1); // the variable i need to use later outside the function
    console.log(cleanup);
    return cleanup;
}

function parseData(url, callBack) {
    Papa.parse(url, {
        header: true,
        download: true,
        dynamicTyping: true,
        complete: function(results) {
            callBack(results.data);
        }
    });
}
const csvfile = document.getElementById('platform').innerHTML; // use element Id to choose file
parseData("/csv/"+ csvfile + ".csv", csvConvert);


test = "1627,2485,1075,3889,3810,23695,7862,1631,4156,9890"
final = `fields name,summary,cover.image_id; where id = (` + csvConvert.cleanup + `); limit 50; sort first_release_date;`; //csvConvert.cleanup coming back as undefined
console.log(final);
 xhr = new XMLHttpRequest();
xhr.onload = success; // call success function if request is successful
xhr.open("POST", "https://foo.execute-api.us-west-2.amazonaws.com/production/v4/games/");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("x-api-key", "foo");

xhr.send(final); // send the request to the server.
console.log(this.responseText);

function success () {
    if (xhr.readyState == 4) {
        if (xhr.status === 200) {
    const platform = document.getElementById('platform').innerHTML;
    var json = JSON.parse(xhr.responseText); //parse the string to JSON
    // FETCHING DATA FROM JSON FILE
        var tr;
    // build the table
for (var i = 0; i < json.length; i++) {
    tr = $('<tr/>');
    tr.append("<td>" 
    + '<div class="image">'   
    + '<img src = "https://images.igdb.com/igdb/image/upload/t_cover_big/' 
    + json[i].cover.image_id
    + ".png" 
    + '"></img>'
    + "</div>" 
    + "</td>");

    tr.append("<td>" 

    + '<div class="name">' 
    + json[i].name 
    + "</div>" 

    + '<div class="summary">'
    + json[i].summary 
    + "</div>" 

    + "</td>");
    
    $('table').append(tr);
    
}}}};
原有代码逻辑
  • 通过PapaParse下载解析指定路径的CSV文件
  • 在csvConvert回调中处理解析数据,清洗后赋值给全局变量window.cleanup
  • 后续拼接cleanup的值构造API查询语句,通过XHR发送POST请求拉取游戏数据
  • 请求成功后解析返回的JSON,动态渲染包含游戏封面、名称、简介的表格
问题现象

访问csvConvert.cleanup取值时始终返回undefined;使用硬编码的test测试变量替换该位置时,后续XHR请求、表格渲染逻辑均可正常运行,仅cleanup变量无法正确获取处理后的值。

问题根因
  1. 取值路径错误:代码把清洗后的值挂载到了window.cleanup上,而非csvConvert函数的属性上,csvConvert.cleanup本身就不存在。
  2. 核心为异步时序问题:Papa.parse下载、解析CSV是异步操作,调用parseData后,主线程代码不会等待CSV解析完成、csvConvert回调执行完毕,就会直接向下执行拼接查询语句、发送XHR请求的逻辑。此时csvConvert还未触发执行,window.cleanup尚未被赋值,自然拿到undefined。
修复方案

不要依赖全局变量跨异步流程传值,把所有需要用到cleanup结果的逻辑,全部放到csvConvert回调内部执行,确保拿到清洗后的数据再拼接查询语句、发送请求。
修复后核心代码如下:

function csvConvert(data) {
    console.table(data);
    const results = data.map(element => ({id: element.id}))
    const string = JSON.stringify(results);
    const cleanup = string.replace(/[&\/\\#+()$~%.'":*?<>{}]/g, '').replace(/id/g, '').replace(/null/g, '').slice(0, -2).substring(1);
    console.log(cleanup);

    // 拿到cleanup后再构造查询语句、发请求
    const final = `fields name,summary,cover.image_id; where id = (${cleanup}); limit 50; sort first_release_date;`;
    console.log(final);
    const xhr = new XMLHttpRequest();
    xhr.onload = function() {
        if (xhr.readyState == 4 && xhr.status === 200) {
            const json = JSON.parse(xhr.responseText);
            let tr;
            for (let i = 0; i < json.length; i++) {
                tr = $('<tr/>');
                tr.append(`<td>
                    <div class="image">
                        <img src="https://images.igdb.com/igdb/image/upload/t_cover_big/${json[i].cover.image_id}.png"></img>
                    </div>
                </td>`);
                tr.append(`<td>
                    <div class="name">${json[i].name}</div>
                    <div class="summary">${json[i].summary}</div>
                </td>`);
                $('table').append(tr);
            }
        }
    }
    xhr.open("POST", "https://foo.execute-api.us-west-2.amazonaws.com/production/v4/games/");
    xhr.setRequestHeader("Accept", "application/json");
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.setRequestHeader("x-api-key", "foo");
    xhr.send(final);
}

function parseData(url, callBack) {
    Papa.parse(url, {
        header: true,
        download: true,
        dynamicTyping: true,
        complete: function(results) {
            callBack(results.data);
        }
    });
}
const csvfile = document.getElementById('platform').innerHTML;
parseData(`/csv/${csvfile}.csv`, csvConvert);

额外优化:移除了不必要的全局变量声明,所有变量限定在对应作用域内,避免全局污染;去掉了无用的test变量、回调外无意义的this.responseText打印(发送请求时响应还未返回,打印无意义)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:36:24