после пустить в Promise.all() ?
https://caolan.github.io/async/v3/docs.html#cargo если нужна очередь асинхронная. я бы попробовал через это сделать. Promise.all - может привести к генерации большеогоо количество запросов, например у тебя 1000 элементов массива и будет 1000 запросов - могут забанить) ну и если что-то реджектнися, то все свалится. Если нужна обработка ответов, то лучше allSettled делать
Мне нужно именно поместить побольше запросов, чтобы я мог одновременно хоть 10 обрабатывать сразу. А очередь как раз будет ограничивать
Я посмотрел и пока не понял как это будет работать
То есть нужно что-то в подобном духе сделать? let promises = [] let page = 1 while (page < 50) { promises.push(limit(() => fetch(page))) page++ } const result = await Promise.all(promises)
Ну это ограничит количество одновременных запросов до 50-ти, но будет неэффективно: чтобы отправить новые запросы тебе нужно ждать результата всей пачки Поэтому и нужно использовать httpAgent, или p-limit (можно и p-queue, но судя по всему тебе хватит p-limit, а он значительно проще) Чтобы был пул из одновременно запущенных 50-ти запросов, и по мере получения ответов он заполнялся бы из очереди
Да, мне и надо до n запросов ограничить и проверить. Да я и поставлю concurrency параметр в 100 запросов например. Главное в бан не попасть и вот поэтому параметр буду пододвигать к реальности.
А мне надо каждый раз заголовок на сокеты отправлять или как? У меня просто axios отправляет запросы с keep-alive но maxFreeSockets не выставляю
let match, promises = [] for (let page = 1; page <= 50; page++) { promises.push(limit(() => mainFunc(page))) } for (let p of promises) { let result try { result = await p } catch (err) { console.log(err) } if (result != null) { match = r break } } limit.clearQueue() Я примерно правильно реализовал? Сделал подобный цикл, потому что мне нужно контролировать ответ и выходить из цикла сразу и стопать очередь
Нет Ты запросы кидаешь пачкой, но потом поочерёдно ждёшь завершения каждого из них. Если ответ на первый придёт через 10 секунд, а ответ на остальные через секунду, ты всё равно прождёшь 10 секунд для того, чтобы начать разгребать ответы на те запросы, ответ на которые давно получен
Ааа точно. Но меня просто устроила скорость поэтому и подумал что так быстрее получилось.
Тогда получается если я кидаю пачками, то получаю долго ожидание ответа и только в конце могу фильтровать ответ
Поэтому я и думал про потоки как вариант что выполнять в нескольких потоках быстрее и всегда можно управлять ответом
Смысл параметра concurrency в том, что ограничивается количество одновременно выполняющихся задач. Как только одна из них завершается, на её место приходит другая из очереди Думаю тебе надо отрабатывать результат запроса сразу, а не ждать результата сразу пачки запросов
То есть вообще обходится без очередей, промисов и просто слать запросы рекурсивно?
Я не знаю особенностей твой задачи Но судя по тому коду, что ты скидывал, запросы у тебя не зависят друг от друга Поэтому я бы делал как раз - промисы, p-limit
Ну вся суть задачи сходить 50 раз в одно место рекурсивно пока не найдётся значение match. И сделать это нужно максимально быстро
Ну тогда в твоём коде надо просто убрать цикл for При получении результата проверять, достигнуты ли условия. Если достигнуты - сбрасывать очередь Так как промис (пока что) отменить нельзя - уже отправленные запросы всё равно отстреляются, можно просто проигнорировать их результаты Только я бы не по 50 запросов отправлял одновременно. Надо исследовать и найти оптимальное для тебя значение
Я по 4 отправляю. Но я не понял как мне этим результатом оперировать. Promise.all же все выполняет или я могу через then получить значения?
Ну да, самое очевидное решение - добавить then Или написать функцию которая делает вызов и анализирует результат, и в очередь ставить эту функцию
Попробую тогда с then. Надеюсь он не будет ждать всех промисов
что значит "надеюсь"? надо просто разобраться с тем, как работает нода и что такое промисы
Я понимаю что промисы будут дальше выполняться потому что они сгенерированы в моём цикле и нода в Promise.all уже их всех будет выполнять
Я сейчас попробовал ограничить создание промисов. Я понимаю что промисы в цикле создаются и нода их полюбому должна исполнить. И что их можно только очистить из очереди заранее до вызова Promise.all. Правильно же я понял? Я в цикле задал количество промисов равное concurrency и начал создавать их, но я столкнулся с такой проблемой. Вынес переменную page за цикл и инкрементировал её. Соответственно промисы имея доступ к переменной просто получали самое последнее её инкрементируемое значение при вызове резолвов промисов
А вот теперь понял. Залез в мдн.
clearQueue есть для очистки очереди Её можно вызвать и после вызова promise.all Второй абзац не понял Зачем тебе цикл по размеру concurrency? Либа сама следит за количеством одновременно запущенных запросов. Тебе сразу всё нужно закинуть в массив Пассаж про переменную я не понял
Я через цикл сгенерировал 50 промисов и запихнул в Promise.all Мне дополнительно как можно остановить очередь? Зачем мне после Promise.all вызывать остановку, если Promise.all промис выполнится только после того как все промисы будут завершены.
ты используешь p-limit? если да, прочитал его доку?
Я правильно понял что я туда могу передать функцию которая остановит задачу?
let match, promises = [] for (let page = 1; page <= 50; page++) { promises.push(limit(() => mainFunc(page))) } const result = await Promise.all(promises) match = result.filter(v => v != null) limit.clearQueue() Вот что сейчас есть. Что мне конкретно передавать в аргументы limit и как это обрабаоть можно?
в dpaste код посмотри
Посмотрел. Не понимаю что там
запрос через axios делается там надо еще понимать redux и ssr
Я тут с промисами не могу разобраться 😂
@js_noobs_ru
Гениальный ответ
Тебе для каждого промиса надо прописать then, который анализирует ответ и сбрасывает очередь, если искомое найдено Мы уже были на этом шаге, и я уже предлагал варианты t.me/nodejs_ru/713505
Типо так ? promises.push(limit(() => mainFunc(page)).then(res => {if (res === null) limit.clearQueue()})
нет тебе нужен анализ результата вызова mainFunc, а не limit
Как понять анализ результата? Мне mainFunc возвращает либо значение либо null. Это я и указал в then
promises.push(limit(() => mainFunc(page).then(res => {if (res != null) limit.clearQueue()}))
Обсуждают сегодня