Node.js中函数外部无法深度复制字典及request调用API后数组打印为空的问题求助
关于Node.js中对象复制与异步操作的问题解答
一、为什么你的控制台打印出空数组?
这是因为request是异步函数,它的回调函数会在API请求完成后才执行,而你写的console.log(copy)是在主代码流程里同步执行的——也就是说,当控制台打印copy的时候,API请求还没完成,回调里的copy.push(...)根本还没运行,所以copy自然是空数组。
简单梳理下代码执行的时间线:
- 初始化
copy为空数组 - 调用
request发起API请求(请求开始,但不会立刻拿到结果) - 直接执行
console.log(copy),此时copy还是空的 - 一段时间后API请求完成,回调函数触发,才把复制后的body推入
copy
解决方法
你需要把依赖异步操作结果的代码放到回调函数里,或者用async/await优化异步流程:
方法1:把打印操作移到回调内部
let copy = []; const request = require('request'); request('https://www.omdbapi.com/?t=JOKER&apikey=b04f2804', { json: true }, (err, res, body) => { if (err) { return console.log(err); } copy.push(JSON.parse(JSON.stringify(body))); console.log(copy); // 现在能正确打印出内容了 });
方法2:用async/await重构(代码更易读)
注意request本身不支持Promise,我们可以用util.promisify把它转换成Promise形式:
const request = require('request'); const { promisify } = require('util'); const requestPromise = promisify(request); async function fetchMovie() { let copy = []; try { const res = await requestPromise('https://www.omdbapi.com/?t=JOKER&apikey=b04f2804', { json: true }); const body = res.body; copy.push(JSON.parse(JSON.stringify(body))); console.log(copy); } catch (err) { console.log(err); } } fetchMovie();
二、为什么无法在函数外部深度复制body对象?
核心原因还是异步时机问题:body对象是在request的回调里才被赋值的,在回调外部的代码执行时,body还没有拿到API返回的数据(甚至还未被初始化),你根本没法对一个还不存在的对象做深度复制。
另外补充下JSON.parse(JSON.stringify())这种复制方式的局限性,方便你后续场景参考:
- 无法复制函数、Symbol类型的属性
- 处理不了存在循环引用的对象
- 会把Date对象转成字符串,RegExp对象转成空对象
- 无法复制对象原型链上的属性
如果需要更可靠的深度复制,你可以自己实现递归复制函数,或者用成熟的工具库(比如lodash的_.cloneDeep)。
自定义递归深度复制函数示例
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; // 处理特殊对象类型 if (obj instanceof Date) return new Date(obj.getTime()); if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags); // 区分数组和普通对象 const cloneObj = Array.isArray(obj) ? [] : {}; // 遍历自身属性并递归复制 for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key]); } } return cloneObj; }
使用时直接替换JSON.parse(JSON.stringify(body))即可:
copy.push(deepClone(body));
内容的提问来源于stack exchange,提问作者Jauri Cortes Cardenas
相关产品推荐
相关产品推荐

