使用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
相关产品推荐
相关产品推荐

