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

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

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

40 ответов

30 просмотров

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта