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

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

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

40 ответов

29 просмотров

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()}))

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

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

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
у вас два процесса. один посылает другому сигнал. у вас есть код обоих процессов? если всё не так - расскажите как оно на самом деле. а именно кто кому чего, есть-ли консоли,...
Karagy
6
Карта сайта