异步操作后pilotsList数组为空问题排查求助
问题:异步获取飞行员数据后
pilotsList始终为空的原因及解决方法 问题根源
你代码里的核心问题出在ndzDrones.forEach(async (drone) => { ... })这段逻辑:
forEach不会等待传入的异步函数执行完成,它会直接遍历完所有元素后继续执行后续代码- 当你执行到
console.log(pilotsList)和res.status(200).json(pilotsList)时,所有请求飞行员数据的fetch还在异步处理中,pilotsList还没被填充,所以输出空数组
另外还有两个次要问题:
- 判断数组是否为空时,用
dronesList !== ""和ndzDrones !== ""是无效的,数组和空字符串永远不会相等,应该用dronesList.length > 0来判断数组是否有元素 - 代码里混合使用了
await和.then(),统一用await能让代码更易读
解决方案
把forEach替换成map,生成一个包含所有异步请求的Promise数组,然后用Promise.all等待所有请求完成,再把结果赋值给pilotsList。
修改后的完整代码
let dronesList = [] let ndzDrones = [] try { // 统一用await替代.then,避免混合写法 const res = await fetch("https://assignments.reaktor.com/birdnest/drones") const xml = await res.text() const jsonData = parser.parse(xml) const dronesData = jsonData.report.capture.drone; dronesList = dronesData; // 修正数组非空判断 if(dronesList.length > 0){ // 用filter替代map+concat,更简洁地筛选违规无人机 ndzDrones = dronesList.filter(drone => { const x = Number(drone.positionX) const y = Number(drone.positionY) return checkVoilation(x, y) }) } let pilotsList = [] // 修正数组非空判断 if(ndzDrones.length > 0){ // 用map生成Promise数组,Promise.all等待所有请求完成 const pilotPromises = ndzDrones.map(async (drone) => { const serial = drone.serialNumber const response = await fetch(`https://assignments.reaktor.com/birdnest/pilots/${serial}`) return await response.json() }) // 等待所有请求完成,将结果赋值给pilotsList pilotsList = await Promise.all(pilotPromises) } console.log(dronesList) console.log(ndzDrones) console.log(pilotsList) res.status(200).json(pilotsList) } catch (error) { console.error('Error:', error) res.status(404).json({message: error.message}) }
关键改动说明
- 替换forEach为map+Promise.all:
ndzDrones.map(async ...)会返回一个每个元素都是Promise的数组,每个Promise对应一个飞行员数据的请求await Promise.all(pilotPromises)会等待所有Promise都resolve,然后将所有返回的飞行员数据组成数组赋值给pilotsList
- 修正数组非空判断:用
array.length > 0替代和空字符串的比较,正确判断数组是否有元素 - 用filter简化筛选逻辑:原来的
map+concat可以用filter直接生成违规无人机数组,代码更简洁高效 - 统一异步写法:去掉
.then(),全部用await,代码结构更清晰,也更容易捕获错误
内容的提问来源于stack exchange,提问作者tsm009
相关产品推荐
相关产品推荐

