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

使用Promise处理XMLHttpRequest后打印数组返回数值而非预期数组如何修复

问题根因

错误出在 allTasks = allTasks.push.apply(allTasks, myData) 这行代码。
JavaScript 中数组的push()方法返回值是执行插入操作后数组的最新长度,不是修改后的数组本身。你将push的返回值重新赋值给了allTasks,原本的数组变量被覆盖为数字类型,自然无法调用forEach等数组原型方法。

修复方案

删掉多余的赋值操作即可,push.apply本身会直接修改原allTasks数组,不需要二次赋值:

// 原错误代码
// allTasks = allTasks.push.apply(allTasks, myData)
// 替换为以下任意一种写法
// 兼容旧版写法
allTasks.push.apply(allTasks, myData)
// ES6+ 更简洁的解构写法
// allTasks.push(...myData)

可选优化

你可以调整Promise的传参逻辑,减少对全局变量的依赖,同时补充错误捕获避免请求失败时无提示:

let allTasks = []

// Read data
const dataPromise = new Promise((resolve, reject)=>{
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4) {
            if(xhttp.status ==200){
                const myData = JSON.parse(this.responseText)
                allTasks.push(...myData)
                resolve(myData) // 将数据直接传递给后续回调
            }else{
                reject(new Error(`数据请求失败,状态码:${xhttp.status}`))
            }
        }
    }
    xhttp.open("GET", "data.json", true);
    xhttp.send();
})
    
dataPromise.then((myData)=>{
    dataUse(myData)
}).catch(err=>{
    console.error(err)
})

// Show data
const dataUse = (taskList = allTasks) =>{
    console.log(taskList)
    // 原有渲染逻辑保持不变即可
    const todos = document.querySelector('.todo')
    const todoInput = document.getElementById('new-todo')
    const added = document.getElementById('added')
    const itemsLeft = document.querySelector('.items-left > span')
    
    taskList.forEach((datas)=>{
        const todo = document.createElement('div')
        todos.appendChild(todo)
        
        const input = document.createElement('input')
        input.setAttribute('type', 'checkbox')
        input.setAttribute('id', datas.name)
        input.setAttribute('class', 'checks')
        todo.appendChild(input)
        
        const label = document.createElement('label')
        label.setAttribute('for', datas.name)
        label.setAttribute('class', `${datas.name} tasks`)
        todo.appendChild(label)
        
        const span = document.createElement('span')
        label.appendChild(span)
        
        const paragraph = document.createElement('p')
        paragraph.innerHTML = datas.todo
        label.appendChild(paragraph)
    })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:06:03