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

Node.js中函数外部无法深度复制字典及request调用API后数组打印为空的问题求助

关于Node.js中对象复制与异步操作的问题解答

一、为什么你的控制台打印出空数组?

这是因为request是异步函数,它的回调函数会在API请求完成后才执行,而你写的console.log(copy)是在主代码流程里同步执行的——也就是说,当控制台打印copy的时候,API请求还没完成,回调里的copy.push(...)根本还没运行,所以copy自然是空数组。

简单梳理下代码执行的时间线:

  1. 初始化copy为空数组
  2. 调用request发起API请求(请求开始,但不会立刻拿到结果)
  3. 直接执行console.log(copy),此时copy还是空的
  4. 一段时间后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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:17:31