Отказ от ответственности: у меня нет опыта в программировании или в сетях в целом, поэтому я могу упустить что-то совершенно очевидное.
Так что я делаю функцию в node.js, которая должна go над массив ссылок на изображения из моей базы данных и проверьте, работают ли они до сих пор. Нужно проверить тысячи ссылок, поэтому я не могу просто отключить несколько тысяч вызовов одновременно и ждать результатов, вместо этого я разбиваю запросы 10: 10 и выполняю головные запросы, чтобы минимизировать использование полосы пропускания.
У меня есть две проблемы.
Первый - это то, что после быстрой загрузки первых 10-20 ссылок другие запросы занимают немного больше времени, и у 9 или 10 из 10 из них истечет время ожидания. Это может быть связано с каким-то сетевым механизмом, который душит мои запросы, когда многие запускаются одновременно, но я думаю, что это, вероятно, связано с моей второй проблемой.
Вторая проблема заключается в том, что процесс проверки замедляется после нескольких итераций. Вот схема того, что я делаю. Я беру строковый массив ссылок на изображения и нарезаю его 10 на 10, а затем проверяю эти 10 сообщений в 10 обещаниях: (игнорируем переменные i и j, они там просто для отслеживания отдельных обещаний и тайм-аутов для регистрации / отладки )
const partialResult = await Promise.all(postsToCheck.map(async (post, j) => await this.checkPostForBrokenLink(post, i + j)));
в пределах checkPostForBrokenLink У меня есть гонка между выборкой и тайм-аутом в 10 секунд, потому что я не хочу ждать истечения времени ожидания соединения каждый раз, когда тайм-аут является проблемой, я дайте ему 10 секунд, а затем отметьте его как истекший тайм-аут и продолжайте.
const timeoutPromise = index => {
let timeoutRef;
const promise = new Promise<null>((resolve, reject) => {
const start = new Date().getTime();
console.log('===TIMEOUT INIT===' + index);
timeoutRef = setTimeout(() => {
const end = new Date().getTime();
console.log('===TIMEOUT FIRE===' + index, end - start);
resolve(null);
}, 10 * 1000);
});
return { timeoutRef, promise, index };
};
const fetchAndCancelTimeout = timeout => {
return fetch(post.fileUrl, { method: 'HEAD' })
.then(result => {
return result;
})
.finally(() => {
console.log('===CLEAR===' + index); //index is from the parent function
clearTimeout(timeout);
});
};
const timeout = timeoutPromise(index);
const videoTest = await Promise.race([fetchAndCancelTimeout(timeout.timeoutRef), timeout.promise]);
если fetchAndCancelTimeout завершится раньше, чем timeout.promise, он отменит этот тайм-аут, но если тайм-аут заканчивается первым, обещание все еще остается. "разрешение" в фоновом режиме, несмотря на то, что код перешел. Я предполагаю, что именно поэтому мой код замедляется. Более поздние тайм-ауты занимают от 20 до 30 секунд от установки до запуска, несмотря на то, что установлены на 10 секунд Насколько я знаю, это должно быть из-за того, что основной процесс занят и у него нет времени для выполнения очереди событий, хотя я действительно не знаю, что он может делать, за исключением ожидания разрешения обещаний.
Итак, вопрос в том, во-первых, я делаю что-то глупое, чего я не должен делать, и это заставляет все быть медленными? Во-вторых, если нет, могу ли я как-нибудь вручную остановить выполнение обещания выборки, если время ожидания истекло, чтобы не тратить ресурсы на бессмысленный процесс? Наконец, есть ли лучший способ проверить, действительно ли большое количество ссылок, что я здесь делаю?