darsga qaytish
Ushbu material faqat quyidagi tillarda mavjud: . Iltimos, bizga Oʻzbek ga tarjima qilishda yordam bering.

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)));