Показать сообщение отдельно
  #3 (permalink)  
Старый 05.12.2020, 23:30
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Я попытался написать.
У меня работало.
Использовал GET вместо POST для удобства.
Может сложновато получилось, но как есть

const getpreq = async (areq, maxreq) => {
	const mres = new Map(); // Набор запросов, выполняемых в данный момент url => индекс
	const pres = [];  // Массив, в который записываются обещания выполнения запросов 
					// В виде {responce: Promise (выполнения запроса для уникальных)
					// Или {index: номер предыдущего запроса, для повторяющихся

// Функция ожидает, когда можно быдет выполнять следующий запрос
	const mayaddreq = async () => {
		if (mres.size < maxreq) return true;
		// Формируем массив обещаний из выполняющихся запросов и ждем, когда какой-нибудь выполнится
		await Promise.any([... mres.values()].map (ind => pres[ind]))
		return true;
	}

// Добавляет новый запрос	
	const addreq = (i, url) => {

		let p = fetch(url, {  // Обещание выполнение запроса
            method: 'GET',
//            body: "statistics",
//            keepalive: true
        })
        let mp = p.then (res => {  // Кошда запрос выполнится
			mres.delete(url);      // Удалить его из списка выполняемых
			return {responce:res}  // Вернуть ответ
        })
        mres.set (url, i)   // Записать в список выполняемых
        return mp        // Возвращаем обещание
	}
	
	
	for (let i= 0; i< areq.length; i++) {
		const url = areq[i];
		let si = areq.indexOf(url)
		if (si>=0 && si < i) {      // Это повторяющийся запрос
			pres.push( {index:si})
		} else {
			await mayaddreq ()     //  Ждем, когда можно начать выполнять
			pres.push (addreq (i, url)) // Выполняем запрос и записываем обещание в массив
		}
	}
	return pres
}

// Функция получает массив вида [{responce: ответ responce от fetch} или {index: номер исходного responce для повторяющихся} ...]
// Возвращает массив результатов обработки responce
const getans = async (aresp) => {
	let aansp = []   // массив обещаний обработки responce
	aresp.forEach ((r, i, ar) => {     // в данном случае я использую responce.text
		aansp[i] = r.responce? r.responce.text() : Promise.resolve(aansp[r.index])
	})
		
	return Promise.all (aansp)  
}

aurls = [
'testaj.php?num=1&val=10',
'testaj.php?num=2&val=20',
'testajm.php?num=3&val=30',
'testajm.php?num=4&val=40',
'testaj.php?num=5&val=50',
'testajm.php?num=6&val=60',
'testaj.php?num=7&val=70',
'testajm.php?num=6&val=60',
'testaj.php?num=2&val=20',
'testajm.php?num=6&val=60',
'testajm.php?num=3&val=30',
'testajm.php?num=8&val=80',
'testajm.php?num=8&val=80',
'testajm.php?num=8&val=80',
'testaj.php?num=9&val=90',
'testaj.php?num=1&val=10',
]

const main = async () => {
	let prec = await getpreq (aurls, 5) 
	let aresp = await Promise.all (prec)
	let ans = await getans (aresp)
	console.log (ans)
}

main()


Зы Предполагается, что запросы выполняются без ошибок.
С обработкой ошибок сложнее будет.

Последний раз редактировалось voraa, 05.12.2020 в 23:39.
Ответить с цитированием