#javascript #axios #httprequest #synchronous
#javascript #axios #httprequest #синхронный
Вопрос:
Приложение, которое я создаю, включает отправку видеокадров на сервер для обработки. Я использую Axios для отправки POST-запроса на сервер. Я намерен отправлять около 3-5 кадров (POST-запрос) в секунду. Мне нужно отправить один после завершения предыдущего запроса, потому что следующий запрос содержит данные в теле запроса, которые зависят от ответа на предыдущий запрос.
Я попытался запустить его в цикле, но это не сработает, потому что следующий запускается до завершения предыдущего. В текущем коде у меня есть что-то вроде этого —
const fun = () => {
axios.post(url,data)
.then((res) => {
// process the response and modify data accordingly
// for the next request
})
.finally(() => fun());
};
Таким образом, я могу непрерывно выполнять запросы один за другим. Но я не могу контролировать количество запросов, которые отправляются в секунду. Могу ли я каким-либо образом ограничить количество запросов в секунду, скажем, не более 5?
Дополнительная информация: я использую это для веб-приложения, где мне нужно отправлять видеокадры с веб-камеры (как URI данных) на сервер для обработки изображений, а результат после этого возвращается клиенту. Я хочу ограничить количество запросов, чтобы уменьшить количество интернет-данных, потребляемых моим приложением, и, следовательно, хотел бы отправлять не более 5 запросов в секунду (желательно равномерно распределенных). Если есть лучший способ, которым Axios отправляет запросы для этой цели, пожалуйста, предложите 🙂
Комментарии:
1. Просто мои 2 цента, это звучит как отличный пример использования websockets, если они поддерживаются серверной частью.
2. Вы смотрели на узкое место? npmjs.com/package/bottleneck
3. @VladimirBogomolov Я знаю, что могу использовать websockets. Просто интересно, есть ли у моего метода какие-либо недостатки или недостатки? Я использую python и flask в серверной части, поэтому websockets, вероятно, поддерживается
4. @Ak47 преимущество websockets заключается в том, что вы можете отправлять данные обратно и вперед без постоянного рукопожатия, которое обычно требуется для каждого запроса post / get. Как только вы открываете канал websocket, потоковая передача данных становится действительно простой, и для серверной части обработка данных websocket обходится дешевле, чем непрерывные запросы post.
Ответ №1:
Здесь вам на помощь может прийти удивительная библиотека под названием Bottleneck. Вы можете ограничить количество запросов в секунду любым желаемым числом, используя следующий код:
const Bottleneck = require("bottleneck");
const axios = require('axios');
const limiter = new Bottleneck({
maxConcurrent: 1,
minTime: 200
});
for(let index = 0; index < 20; index ){
limiter.schedule(() => postFrame({some: 'data'}))
.then(result => {
console.log('Request response:', result)
})
.catch(err => {
console.log(err)
})
}
const postFrame = data => {
return new Promise((resolve, reject) => {
axios.post('https://httpstat.us/200', data)
.then(r => resolve(r.data))
.catch(e => reject(e))
});
}
Манипулируя ограничителем
const limiter = new Bottleneck({
maxConcurrent: 1,
minTime: 200
});
Вы можете запустить свой запрос axios в любом случае с любым параллелизмом.
Например, чтобы ограничить количество запросов в секунду до 3, вы должны установить minTime
значение 333
. Само собой разумеется, если вы хотите ограничить его до 5 в секунду, оно должно быть установлено 200
равным .
Пожалуйста, обратитесь к документации по узкому месту здесь: https://www.npmjs.com/package/bottleneck
Комментарии:
1. Спасибо… Похоже, это сработает в моем случае. Я попробую это
2. Я попробовал библиотеку, но она не работает для бесконечных циклов. В моем случае я должен поддерживать выполнение запроса до тех пор, пока клиент не остановит его. Кажется, что библиотека ставит в очередь весь запрос с самого начала и останавливается, чтобы достичь минимального времени для каждого запроса. Я думаю, было бы сложно, если бы я хотел, чтобы он работал в течение длительного времени, поскольку вся очередь ставится в очередь с самого начала. Есть ли способ, которым я могу просто запланировать 5 запросов в секунду и выполнять их бесконечно, не поддерживая очередь, как это делает эта библиотека?
3. @Ak47 Не с моей головы. Это то, о чем я подумаю, но пока позвольте мне указать, что я использую именно этот код для публикации записей из файла построчно с помощью axios. Я отправляю 4 запроса в секунду. Некоторые файлы содержат буквально миллионы строк, и эта присоска каждый раз работает как шарм на довольно обычном оборудовании. Так что, если вас конкретно беспокоит то, что в конечном итоге будет использовано слишком много ресурсов, я бы сказал, что с вами, вероятно, все будет в порядке. У него есть отличная
limiter.stop()
функция для произвольного прерывания выполнения.4. Кажется, что он работает до сотен тысяч в цикле, но начинает отставать, если я больше не увеличиваю цикл. Вероятно, это означает, что он потребляет ресурсы. Хотя моего usecase достаточно для гораздо меньшего количества циклов, но мне просто интересно, есть ли способ справиться со случаем, когда запросы должны выполняться бесконечно. Я посмотрю, есть ли способ достичь того, что я описал выше. Спасибо за помощь 🙂
5. @Ak47 Очень интересное наблюдение. Вы запускаете свой процесс в браузере? Я отказываюсь от какого-либо опыта использования Bottlenck в браузере, поскольку мои материалы выполняются на узловом сервере.