无法在空数组中推送数据,我正在使用 Node js 中的 https 模块从外部 API 获取该数据



var https = require("https");
const arr = [];
for (let i = 1; i < 26; i++) {
https.get(
`https://jsonmock.hackerrank.com/api/countries?page=${i}`,
(res) => {
res.on("data", (data) => {
JSON.parse(data).data.map((info, i) => {
let { name } = info;
arr.push(name);
console.log(name);
});
});
}
);
}
console.log(arr);

当我只是记录json。parse(data)我得到所需的数据在我的控制台

但是当我试图将它放入数组时它不会发生相反它会将一个空数组记录到控制台

我真的需要知道原因,因为我已经被这个困了3天了

你的问题是对https.get的回调-即(res) =>被异步地称为-因此,console.log(arr);在25个https.get请求之前被执行-你会看到arr.push实际上是工作的,如果你在console.log(name);的地方console.log(arr);-所以你的假设你不能推是不正确的

当数组中有数据时,你永远不会使用console.log

我想我可以建议的一种方法是使用旧版本的Node.js(14.16.0),如下所示

var https = require("https");
function fn(callback) {
const result = [];
let done = 0;
for (let i = 1; i < 26; i++) {
https.get(`https://jsonmock.hackerrank.com/api/countries?page=${i}`, (res) => {
res.on("data", (data) => {
JSON.parse(data).data.map((info) => {
let { name } = info;
result.push(name);
console.log(name);
});
// keep track of how many requests have "completed"
done = done + 1;
// when all are done, call the callback
if (done === 25) {
callback(result);
}
});
});
}
}
fn(arr => { // here is where arr is populated, nowhere else
console.log(arr);
});

注意,arr只能在回调内部访问——你不能像你想的那样在顶层访问arr——唯一可能的方法是使用支持顶层await的Node.js版本——并将代码转换为使用Promise(这是一个微不足道的任务)

不确定这是否重要,但不能保证arr中的名称将按正确的顺序排列…例如,迭代3的结果可能会在迭代4之后推送,因为这是网络请求的本质,所以无法保证它们何时完成


顺便说一下。如果您要使用最新版本的node.js(撰写本文时为18.1)-上面的代码可以写成

const promises = Array.from({length:25}, async (_, i) => {
const res = await fetch(`https://jsonmock.hackerrank.com/api/countries?page=${i+1}`);
const data = await res.json();
return data.map(({name}) => name);
});
const arr = (await Promise.all(promises)).flat(2);
console.log(arr);

值得注意的是

  1. 原生fetch-与常规node.js方法相比,它使网络请求更简单
  2. 顶级await-因此,您可以在代码
  3. 的顶级使用arr
  4. 6行代码vs超过20行

最新更新