170 похожих чатов

Или я могу создать допустим пачку промисов через цикл и

после пустить в Promise.all() ?

40 ответов

11 просмотров

https://caolan.github.io/async/v3/docs.html#cargo если нужна очередь асинхронная. я бы попробовал через это сделать. Promise.all - может привести к генерации большеогоо количество запросов, например у тебя 1000 элементов массива и будет 1000 запросов - могут забанить) ну и если что-то реджектнися, то все свалится. Если нужна обработка ответов, то лучше allSettled делать

Максим-BlindHack Systems Автор вопроса

Мне нужно именно поместить побольше запросов, чтобы я мог одновременно хоть 10 обрабатывать сразу. А очередь как раз будет ограничивать

Максим-BlindHack Systems Автор вопроса

Я посмотрел и пока не понял как это будет работать

Максим-BlindHack Systems Автор вопроса

То есть нужно что-то в подобном духе сделать? 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-ти запросов, и по мере получения ответов он заполнялся бы из очереди

Максим-BlindHack Systems Автор вопроса

Да, мне и надо до n запросов ограничить и проверить. Да я и поставлю concurrency параметр в 100 запросов например. Главное в бан не попасть и вот поэтому параметр буду пододвигать к реальности.

Максим-BlindHack Systems Автор вопроса

А мне надо каждый раз заголовок на сокеты отправлять или как? У меня просто axios отправляет запросы с keep-alive но maxFreeSockets не выставляю

Максим-BlindHack Systems Автор вопроса

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 секунд для того, чтобы начать разгребать ответы на те запросы, ответ на которые давно получен

Максим-BlindHack Systems Автор вопроса

Ааа точно. Но меня просто устроила скорость поэтому и подумал что так быстрее получилось.

Максим-BlindHack Systems Автор вопроса

Тогда получается если я кидаю пачками, то получаю долго ожидание ответа и только в конце могу фильтровать ответ

Максим-BlindHack Systems Автор вопроса

Поэтому я и думал про потоки как вариант что выполнять в нескольких потоках быстрее и всегда можно управлять ответом

Смысл параметра concurrency в том, что ограничивается количество одновременно выполняющихся задач. Как только одна из них завершается, на её место приходит другая из очереди Думаю тебе надо отрабатывать результат запроса сразу, а не ждать результата сразу пачки запросов

Максим-BlindHack Systems Автор вопроса

То есть вообще обходится без очередей, промисов и просто слать запросы рекурсивно?

Я не знаю особенностей твой задачи Но судя по тому коду, что ты скидывал, запросы у тебя не зависят друг от друга Поэтому я бы делал как раз - промисы, p-limit

Максим-BlindHack Systems Автор вопроса

Ну вся суть задачи сходить 50 раз в одно место рекурсивно пока не найдётся значение match. И сделать это нужно максимально быстро

Ну тогда в твоём коде надо просто убрать цикл for При получении результата проверять, достигнуты ли условия. Если достигнуты - сбрасывать очередь Так как промис (пока что) отменить нельзя - уже отправленные запросы всё равно отстреляются, можно просто проигнорировать их результаты Только я бы не по 50 запросов отправлял одновременно. Надо исследовать и найти оптимальное для тебя значение

Максим-BlindHack Systems Автор вопроса

Я по 4 отправляю. Но я не понял как мне этим результатом оперировать. Promise.all же все выполняет или я могу через then получить значения?

Ну да, самое очевидное решение - добавить then Или написать функцию которая делает вызов и анализирует результат, и в очередь ставить эту функцию

Максим-BlindHack Systems Автор вопроса

Попробую тогда с then. Надеюсь он не будет ждать всех промисов

что значит "надеюсь"? надо просто разобраться с тем, как работает нода и что такое промисы

Максим-BlindHack Systems Автор вопроса

Я понимаю что промисы будут дальше выполняться потому что они сгенерированы в моём цикле и нода в Promise.all уже их всех будет выполнять

Максим-BlindHack Systems Автор вопроса

Я сейчас попробовал ограничить создание промисов. Я понимаю что промисы в цикле создаются и нода их полюбому должна исполнить. И что их можно только очистить из очереди заранее до вызова Promise.all. Правильно же я понял? Я в цикле задал количество промисов равное concurrency и начал создавать их, но я столкнулся с такой проблемой. Вынес переменную page за цикл и инкрементировал её. Соответственно промисы имея доступ к переменной просто получали самое последнее её инкрементируемое значение при вызове резолвов промисов

Максим-BlindHack Systems Автор вопроса

А вот теперь понял. Залез в мдн.

clearQueue есть для очистки очереди Её можно вызвать и после вызова promise.all Второй абзац не понял Зачем тебе цикл по размеру concurrency? Либа сама следит за количеством одновременно запущенных запросов. Тебе сразу всё нужно закинуть в массив Пассаж про переменную я не понял

Максим-BlindHack Systems Автор вопроса

Я через цикл сгенерировал 50 промисов и запихнул в Promise.all Мне дополнительно как можно остановить очередь? Зачем мне после Promise.all вызывать остановку, если Promise.all промис выполнится только после того как все промисы будут завершены.

ты используешь p-limit? если да, прочитал его доку?

Максим-BlindHack Systems Автор вопроса

Я правильно понял что я туда могу передать функцию которая остановит задачу?

Максим-BlindHack Systems Автор вопроса

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 код посмотри

Максим-BlindHack Systems Автор вопроса

Посмотрел. Не понимаю что там

запрос через axios делается там надо еще понимать redux и ssr

Максим-BlindHack Systems Автор вопроса

Я тут с промисами не могу разобраться 😂

@js_noobs_ru

Максим-BlindHack Systems Автор вопроса

Гениальный ответ

Тебе для каждого промиса надо прописать then, который анализирует ответ и сбрасывает очередь, если искомое найдено Мы уже были на этом шаге, и я уже предлагал варианты t.me/nodejs_ru/713505

Максим-BlindHack Systems Автор вопроса

Типо так ? promises.push(limit(() => mainFunc(page)).then(res => {if (res === null) limit.clearQueue()})

нет тебе нужен анализ результата вызова mainFunc, а не limit

Максим-BlindHack Systems Автор вопроса

Как понять анализ результата? Мне mainFunc возвращает либо значение либо null. Это я и указал в then

promises.push(limit(() => mainFunc(page).then(res => {if (res != null) limit.clearQueue()}))

Похожие вопросы

Обсуждают сегодня

Скажите, можно ли как-то "переместить" динамический массив из одной переменной в другую? Скажем, переместить из TList<> в TArray<>. Именно переместить, а не скопировать. Если ...
Eugene Krasnikov (ᴊɪɴ x)
37
комрады, че-та лыжы не едут var tmpFont: TFont; begin tmpFont:= TFont.Create; try case rgFontColor.ItemIndex of 0: tmpFont.Color:= clWindowText; 1: tmpFo...
Ed Doc
34
.model small .stack 100h .data a db 'Hello, World!', '$' ; исходная строка b db 20 dup(?) ; строка b с запасом на максимальную длину .code main: ...
Алексей -man
3
М-да. Почему бы просто со stringlist не работать?
Michael Longneck
23
Редактор листа Excel, по сути двумерный массив ячеек. Ячейка - это экземпляр класса, у нее всякие свойства, методы. Проблема в том, что количество используемых строк и колоно...
Sergey Bodrov
2
Интересно, нет ли какого-то способа получить из dll не адрес самой метки, а адрес со смещением?
The Bird of Hermes
54
Is there a digital way to cut the electricity from a usb in linux? It sounds weird, but it's exactly what I need to do. I tried to simulate the unplug/replug but is not the ...
Eduard Rivas
15
Добавляю 100 тыс слов в TListBox. Перемешаю скролл (от ListBox). После примерно 65536 скролл резко прыгает вверх. Это что за глюк? Как фиксить, кто-нибудь знает?
Eugene Krasnikov (ᴊɪɴ x)
8
generic procedure function test<T>(param: T); type case T of longint: NewT = word; longword: NewT = byte; end; var v1: NewT; Как это можно сделать? Чтобы у меня...
notme
21
Делал задачу вот такую https://stepik.org/lesson/4985/step/9?unit=1083 получилось такое https://play.haskell.org/saved/ipKrepqe оно работает, тестов много не писал, но работае...
Fedor
22
Карта сайта