NodeJS: запись в файл ответов на несколько запросов GET по порядку
У меня есть массив URL-адресов, и мне нужно вызвать каждый из них и записать ответ на файл в правильном порядке в формате JSON. Например, [resp1, resp2, resp3,...]
, Однако в приведенном ниже коде я получаю ответы, записанные в файл в случайном порядке. Например, [resp3]resp1,resp2,
, Как я могу предотвратить это в пределах foreach со многими URL-адресами (чтобы я не мог перейти к ним вручную)?
fs.writeFile('my_file.json', "[", (err) => {
if (err) throw err;
});
urls.forEach((url, index) => {
https.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
let output = data;
(index == urls.length) ? output += ']' : output += ','
fs.appendFileSync('my_file.json', output, (err) => {
if (err) throw err;
});
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
});
1 ответ
Рассмотрите возможность сопоставления каждого запроса с обещанием, а затем используйте Promise.all
вместо этого, а затем записать в файл только один раз:
const urlProms = urls.map(url => new Promise((resolve, reject) => {
https.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => resolve(data));
})
.on('error', reject);
}));
Promise.all(urlProms)
.then((dataArr) => {
fs.writeFile('my_file.json', JSON.stringify(dataArr), (err) => {
if (err) throw err;
});
})
.catch((err) => {
// handle errors
});
Создание / объединение строк JSON вручную редко является хорошей идеей. Если вам пришлось сделать это вручную, используйте async
/await
ждать каждой итерации по порядку, чтобы убедиться, что все вставлено в правильном порядке и что перекрывающиеся запросы не занимают слишком много памяти:
const getData = url => new Promise((resolve, reject) => {
https.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => resolve(data));
})
.on('error', reject);
});
(async () => {
fs.writeFileSync('my_file.json', '[', (err) => {
if (err) throw err;
});
for (let i = 0; i < urls.length; i++) {
const data = await getData(urls[i]);
fs.appendFileSync('my_file.json', data, (err) => {
if (err) throw err;
});
}
fs.appendFileSync('my_file.json', ']', (err) => {
if (err) throw err;
});
})();