Как выполнять цикл синхронно, если в нем асинхронная функция?
async  / await /**
 * асинхрота с запросом. Возвращает Promise
 */
const doAsyncStuff = (urlIter, urlSite) => new Promise((resolve, reject) => {
  needle.get(urlIter, (err, result) => { // Сама асинхронная функция
    if (err) reject(err);
    $('.product-card__link')
      .each((i, val) => prodLink.push(urlSite + $(val).attr("href")));

    resolve();
  })
})

/**
 * Тот самый цикл
 * @param {number} quanPage число страниц
 */
const doStuff = async quanPage => {
  for(let i = 1; i <= quanPage; i++) {
    let urlIter = urlSite + i; // Ссылка, которая создается с каждой новой итерацией
    await doAsyncStuff(urlIter, urlSite); // Ждём-с!
  }
}

doStuff(10);
Демо:snippet
Вместо for можно просто использовать функцию, которая циклически вызывает сама себя, пока счетчик удовлетворяет условиям:i = 1;

function ciklotron() {

	if (i <= quanPage) {
		
		let urlIter = urlSite + i; 
		
		needle.get(urlIter, function (err, res) {
			if (err) throw (err);
			
		  prodUrl = $('.product-card__link');  
		  prodUrl.each(function (i, val) {    
				prodLink.push(urlSite + $(val).attr("href"));
		  });

		i = Number(i) + Number(1); // Увелчиваем счетчик на еденицу
		ciklotron(); // Вызываем сами себя
		  
		});

	}

}