Xatolarga bardoshli Promise.all
Parallel ravishda bir nechta URL manzillarini olishni istaymiz.
Buning uchun kod:
let urls = [
"https://api.github.com/users/iliakan",
"https://api.github.com/users/remy",
"https://api.github.com/users/jeresig",
];
Promise.all(urls.map((url) => fetch(url)))
// har bir javob uchun uning holati ko'rsatilgan
.then((responses) => {
// (*)
for (let response of responses) {
alert(`${response.url}: ${response.status}`);
}
});
Muammo shundaki, agar biron bir so’rov bajarilmasa, Promise.all
xato bilan rad etadi va biz boshqa barcha so’rovlarning natijalarini yo’qotamiz.
Bu yaxshi emas.
Kodni (*)
satridagi responses
massivi muvaffaqiyatli olish uchun javob obyektlarini va muvaffaqiyatsiz bo’lganlar uchun xato obyektlarini o’z ichiga olishi uchun o’zgartiring.
Masalan, agar URL manzillaridan biri yomon bo’lsa, u quyidagicha bo’lishi kerak:
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/remy',
'http://no-such-url'
];
Promise.all(...) // URL-larni olish uchun sizning kodingiz...
// ...va natijada olingan a'zolar massivi sifatida fetch xatolarini o'tkazing...
.then(responses => {
// 3 urls => 3 massiv a'zolari
alert(responses[0].status); // 200
alert(responses[1].status); // 200
alert(responses[2]); // TypeError: olinmadi (matn farq qilishi mumkin)
});
P.S. Ushbu vazifada to’liq javobni response.text()
yoki response.json()
yordamida yuklashingiz shart emas. Fetch xatolarni to’g’ri yo’lda boshqaring.
Yechim aslida juda oddiy.
Bunga qarang:
Promise.all(
fetch("https://api.github.com/users/iliakan"),
fetch("https://api.github.com/users/remy"),
fetch("http://no-such-url")
);
Bu yerda bizda Promise.all
ga ketadigan fetch(...)
massivlari mavjud.
Biz “Promise.all” ning ishlash usulini o’zgartira olmaymiz: agar u xato aniqlasa, u holda u rad etadi. Shunday qilib, biz biron bir xato yuzaga kelishining oldini olishimiz kerak. Buning o’rniga, agar fetch
xatosi yuzaga kelsa, biz unga “normal” natija sifatida qarashimiz kerak.
Mana qanday:
Promise.all(
fetch("https://api.github.com/users/iliakan").catch((err) => err),
fetch("https://api.github.com/users/remy").catch((err) => err),
fetch("http://no-such-url").catch((err) => err)
);
Boshqacha qilib aytganda, .catch
barcha va’dalar uchun xatoga yo’l qo’yadi va uni normal ravishda qaytaradi. Va’dalar qanday ishlashining qoidalariga ko’ra, agar .then/catch
ishlovchisi qiymatni qaytarsa (bu xato obyekti yoki boshqa biron bir narsaning ahamiyati yo’q), u holda “normal” oqim davom etadi.
Shunday qilib .catch
xatoni “normal” natija sifatida tashqi Promise.all
ga qaytaradi.
Ushbu kod:
Promise.all(urls.map((url) => fetch(url)));
Quyidagidek, qayta yozish mumkin:
Promise.all(urls.map((url) => fetch(url).catch((err) => err)));