Рекурсивный http запрос, как дождаться последний дочерний элемент и только потом выдать результат?
Сначала получаем родительский обьект, затем надо пройтись по каждому и собрать его дочерние элементы. Сколько в глубь у каждого из обьекта неизвестно. Идти до тех пор пока не пустой. После того только как получит по каждому родительскому обьекту результат, собрать в обьект один (Json) и выдать результат. Вопрос в том как сделать чтобы он ждал результат каждого род. обьекта. Сейчас есть вот такой код, он записывает файл после получения каждой итерации ветки. А нужно как то дождаться последнию ветку и записать результат.
const http = require("http");
const fs = require("fs");
try {
getList();
} catch (e) {
console.log(e.message);
}
function recurs(res, a, parrentInfo, k) {
http.get(
"http:/..." + res,
(resp) => {
let data = "";
resp.on("data", (chunk) => {
data += chunk;
});
resp.on("end", () => {
let count = 0;
if (data !== "[]") {
let dataJson = JSON.parse(data);
a.push(dataJson);
for (let i = 0; i < dataJson.length; i++) {
k++;
recurs(dataJson[i].id, a, parrentInfo, k);
if (count == dataJson.length - 1) {
fs.writeFileSync("5264.json", JSON.stringify(a));
}
count++;
}
} else {
}
});
resp.on("error", (err) => {
console.log({ error: err.message });
});
}
);
}
async function getList() {
http
.get(
"http://...",
(resp) => {
let data = "";
resp.on("data", (chunk) => {
data += chunk;
});
resp.on("end", async () => {
if (data.length > 0) {
let dataJson = JSON.parse(data);
console.log(dataJson.length);
count = 0;
let k = 0;
let a = [];
for (let i = 0; i < 1; i++) {
let parrentInfo = dataJson[i];
let result = await recurs( dataJson[i], a, parrentInfo, k );
}
}
});
}
)
.on("error", (err) => {
console.log({ error: err.message });
});
}
Ответы (1 шт):
Если я не ошибаюсь, вам нужно полностью уйти от колбеков, чтобы построить всю логику внутри одной асинхронной рекурсивной функции. Для этого достаточно промисифицировать http.get() + использовать response как асинхронный итератор (response, как и любой поток чтения, реализует этот интерфейс).
Попробуйте решить при помощи этих кирпичиков:
- Промисифицируем
http.get():
function get(url) {
return new Promise((resolve) => {
https.get(url, (res) => { resolve(res); });
});
}
- Получаем и обрабатываем ответ как асинхронный итератор:
const response = await get(someUrl);
response.setEncoding('utf8');
let json = '';
for await (const chunk of response) {
json += chunk;
}
const object = JSON.parse(json);