Javascript "n" saniye sonra Ajax isteğini iptal etmek
Selamlar,
Bir hedef site adresine istek atarak, http durumunu öğrenmek istiyorum. Eğer http status 200'lü ise ona göre bir aksiyon alacağım.
Ancak şöyle bir problem var; bazı linklere isteği atıyorum ve arkaplanda 25-30 saniye boyunca o istekten cevap gelmesi bekleniyor. Daha sonra timeout veya farklı bir durum ile birlikte yaptığım çağrı sonlanıyor.
Yapmayı istediğim senaryo ise şu şekilde;
JS ile "https://hedefsite.com" adresine bir çağrı yapmak ve HTTP statusunu almak istiyorum. Ancak tüm bu süreç, maksimum 5 saniye sürmeli. Eğer karşı siteye 5 saniye içinde erişemiyorsam, o zaman otomatik olarak çağrıyı başarısız kabul etmek ve ona göre aksiyon almak istiyorum...
Dolayısı ile, Javascript ile, ajax veya farklı bir yöntem aracılığıyla bunu nasıl yapabilirim?
Not: ajax'ın timeout özelliğini kullandım ama işe yaramadı.
Şimdi istediğin 2 şey var:
- 1.si eğer x saniye içinde istek attığın yer cevap dönmezse isteği iptal etmek istiyorsun.
Bunun için fetch'de AbortController
sınıfını kullanabilirsin.
- 2.si ise eğer timeout olursa bunu yakalamak ve buna göre bir işlem yapmak istiyorsun.
Bunun içinde Promise.race
metodunu kullanabilirsin. Bunun içine verdiğin promise'lerden hangisi önce sözünü tutarsa onu döndürüyor. Bu mantıkta fetch zaten promise, senin 2. bir promise yazman lazım bu arkadaşta 5 saniye sonra reject olacak bir promise olacak. Böylece eğer 5 sn uzun süren bir isteğin varsa yazdığın 2. promise sözünü tutacağı için timeout olduğunu anlayacaksın.
Gelelim kodlara:
function fetchWithTimeoutAndAbort(url, timeout = 5000) {
const controller = new AbortController();
const signal = controller.signal;
// Zaman aşımı için bir promise oluştur
const timeoutPromise = new Promise((_, reject) => {
const timeoutId = setTimeout(() => {
controller.abort(); // Zaman aşımında isteği iptal et
reject(new Error('Request timed out and was aborted'));
}, timeout);
});
// Fetch isteği ve zaman aşımı promise'ını yarıştır
return Promise.race([
fetch(url, { signal }).then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.status; // her sey okey ise status'u dondur
}),
timeoutPromise
]);
}
kullanırken ise:
fetchWithTimeoutAndAbort('https://hedefsite.com', 5000)
.then(data => console.log(data)) // Başarılı yanıtı işle
.catch(error => {
if (error.name === 'AbortError') {
console.error('Fetch request was aborted due to timeout');
} else {
console.error('Fetch error:', error);
}
});
Güncelleme
Son çıkanlara baktığımda AbortSignal: timeout()
diye bir şey varmış, yani teknik olarak şöyle de kısaltılabilir:
fetch('https://hedefsite.com', { AbortSignal.timeout(5000) })
.then(res => console.log(res))
.catch(err => console.log(err))