Django/React中JSON.stringify()代码返回空嵌套对象但控制台正常
我在Django/React应用中通过API获取了一个嵌套结构的ID对象,结构如下:
{ "0": { "0": "7y8X0Z04gJCKtfrnSAMywJ", "1": "781V2Y5LPtcpgONEOadadE" }, "1": { "0": "7nCONy10IHp7XD3oYZ0lcx" } }
但用JSON.stringify()序列化这个对象时,结果却是{"0":{},"1":{}, ...},而手动创建的同结构模拟对象testObj能正常序列化,甚至在控制台中把该对象保存后再执行JSON.stringify()也能得到正确结果。我已经用async/await确保对象生成完成,也确认了属性是可枚举的,相关代码如下:
处理对象的函数:
function addItemsToPlaylist(allTopTracksObj, playlistId) { const encodedPlaylistId = encodeURIComponent(playlistId); const testObj = { 0: { 0: '7y8X0Z04gJCKtfrnSAMywJ', 1: '781V2Y5LPtcpgONEOadadE' }, 1: { 0: '7nCONy10IHp7XD3oYZ0lcx', } } console.log('testObj', testObj) console.log('allTopTracksObj', allTopTracksObj) console.log('testObj stringify', JSON.stringify(testObj)) console.log('allTopTracksObj stringify', JSON.stringify(allTopTracksObj)) fetch(`/spotify/add-items-to-playlist/?playlistId=${encodedPlaylistId}`, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, method: "POST", body: JSON.stringify(allTopTracksObj) }) .then(function (res) { console.log('addItemsToPlaylist result', res) }) .catch(function (res) { console.log(res) }) }
调用代码:
await createTopNTracksArray(artistIdArray).then((obj) => { if (Object.keys(obj).length > 0 && playlistId.length > 0) { addItemsToPlaylist(obj, playlistId); }
可能的原因
子属性异步延迟填充:你用
await等待createTopNTracksArray返回,但如果这个函数内部是先返回空对象,再通过嵌套异步操作(比如子API请求、定时器)给对象添加子属性,await只能等到函数返回对象,无法等待内部的异步填充完成。此时代码中执行JSON.stringify时,子对象还是空的,但控制台显示的是对象的实时引用,展开时会显示后续填充的内容,造成“对象已生成”的错觉。对象是特殊类型:如果
allTopTracksObj是Proxy对象或带有自定义原型的类实例,JSON.stringify可能无法正确遍历其属性,导致子对象被序列化为空。
解决方案
方案1:确保createTopNTracksArray返回完全填充的对象
修改createTopNTracksArray函数,让它在所有异步操作完成后再构建完整对象并返回:
async function createTopNTracksArray(artistIdArray) { const result = {}; // 用Promise.all等待所有异步请求完成 await Promise.all(artistIdArray.map(async (artistId, index) => { const tracks = await fetchTopTracks(artistId); // 替换为你的异步获取逻辑 // 组装子对象 result[index] = tracks.reduce((acc, track, trackIndex) => { acc[trackIndex] = track.id; return acc; }, {}); })); return result; }
这样await createTopNTracksArray就能拿到完全填充好的对象,后续JSON.stringify可正常工作。
方案2:将特殊对象转换为普通JS对象
如果对象是Proxy或其他特殊类型,手动递归转换为纯普通对象:
function toPlainObject(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } return Array.isArray(obj) ? obj.map(toPlainObject) : Object.fromEntries( Object.entries(obj).map(([key, val]) => [key, toPlainObject(val)]) ); } // 在addItemsToPlaylist中使用 const plainObj = toPlainObject(allTopTracksObj); // 序列化和发送请求都用plainObj body: JSON.stringify(plainObj)
方案3:验证对象填充时机
在调用addItemsToPlaylist前,先确认子对象是否已填充:
await createTopNTracksArray(artistIdArray).then((obj) => { // 检查第一个子对象的内容 console.log('子对象内容', obj[0]); if (Object.keys(obj).length > 0 && playlistId.length > 0 && Object.keys(obj[0]).length > 0) { addItemsToPlaylist(obj, playlistId); } });
如果这里打印的obj[0]是空的,说明确实是异步填充延迟的问题,需要调整createTopNTracksArray的逻辑。
内容的提问来源于stack exchange,提问作者Alan Grenfell

