asyn c await fetch undefined. Как справиться? - PullRequest
8 голосов
/ 26 мая 2020

В настоящее время я изучаю async await fetch, и я создал следующий пример, чтобы помочь мне в обучении.

Рабочий пример ниже:

  1. извлекает три случайные json записи из Publi c API
  2. извлекает url из каждого возврата json
  3. создает три элемента img
  4. добавляет три элемента img к тело документа.

Обратите внимание, что promise2 имеет намеренно неправильный путь, установленный для принудительного присвоения статуса http 404.

Как мне обработать эту ошибку, если она должна была произойти с любым из три обещания?

// the big promise.
  async function getAsyncData() {

    try {

      // attempt to resolve 3 individual unrelated promises...
      let promise1  = await fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg');
      let promise2  = await fetch('https://dummyimage.com/bad/url/here/48x48/e91e63/ffffff.png&text=.png');
      let promise3  = await fetch('https://dummyimage.com/48x48/00bcd4/ffffff.gif&text=.gif');

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise1.url;
      // ...and add it to our html document body...
      document.body.append(img);

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise2.url;
      // ...and add it to our html document body...
      document.body.append(img);

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise3.url;
      // ...and add it to our html document body...
      document.body.append(img);

    } catch (error) {

      console.log('Try/Catch block error:', error);

    }

    // return {


    // }

  }

  getAsyncData();

Ответы [ 2 ]

4 голосов
/ 26 мая 2020

Используя Promise.allSettled, вы можете запускать все вызовы выборки параллельно и ждать их завершения.

const test = async() => {
  const promise1  = await fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg')
    .then(r => r.url)

  const promise2  = await fetch('https://dummyimage.com/bad/url/here/48x48/e91e63/ffffff.png&text=.png')
    .then(r => r.url)

  const promise3  = await fetch('https://dummyimage.com/48x48/00bcd4/ffffff.gif&text=.gif')
    .then(r => r.url)

  const results = await Promise.allSettled([promise1, promise2, promise3])

  console.log(results);

}

test();

Для более старой поддержки вам нужно будет использовать обещание, которое перехватило бы любые ошибки из выборки.

function makeCall () {
  return new Promise((resolve) => {
    fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg')
    .then(r => console.log(r.url))
    .catch(error => resolve({ error }))
  })
}

const test = async() => {
  const promise1 = makeCall()
  const promise2 = makeCall()
  const promise3 = makeCall()

  const results = await Promise.all([promise1, promise2, promise3])

  console.log(results)

}

test()
1 голос
/ 28 мая 2020

@ suchislife: Честно говоря, ответ, который вы опубликовали, должен быть отдельным вопросом. Я отметил это, потому что это отдельный вопрос. Это не связано с вашим исходным вопросом о получении undefined. Я публикую это здесь только для временного ответа на вашу проблему, но вы должны принять ответ escapello, и это должна быть другая тема. Разрешение подобных вещей засоряет StackOverflow.

@ Модераторы: На самом деле я только сейчас заметил, что @suchislife упомянул обработку 404, но никогда явно не заявлял и не показывал в вашем коде, что вашей целью было отловить ошибки 404, и ваш вопрос касался отдельной ошибки. Я не знаю, как к этому относиться. Я предполагаю, что это считается частью вопроса?

.error и try / catch - это не то, что вы ищете: выборка разрешается, даже если 404?
Вам нужно чтобы проверить значение response.ok. fetch выдает ошибки только при сетевых проблемах, но не в ответах на ошибки.

// Background Colors
const bgHexColors   = ['f44336', 'e91e63', '9c27b0', '673ab7', '3f51b5', '2196f3', '03a9f4', '00bcd4', '009688', '4caf50', '8bc34a', 'cddc39', 'ffeb3b', 'ffc107', 'ff9800', 'ff5722', '795548', '9e9e9e', '607d8b'];
// Foreground Colors
const fgHexColors   = ['ffffff'];
// Image File Extensions
const imgExtensions = ['.png', '.gif', '.jpg'];

// First, we initialize an empty array for promises.
let myPromises = [];

// We then populate this array with 24 promises.
for(let i = 0; i < 24; i++){

  let imgWidth     = 48;
  let imgHeight    = 48;
  let bgHexColor   = bgHexColors[Math.floor(Math.random() * bgHexColors.length)];
  let fgHexColor   = fgHexColors[Math.floor(Math.random() * fgHexColors.length)];
  let imgExtension = imgExtensions[Math.floor(Math.random() * imgExtensions.length)];
  let imgText      = imgExtension;

  // We declare the promise to be added and...
  let myPromise = getRandomImage(imgWidth, imgHeight, bgHexColor, fgHexColor, imgExtension, imgText);

  // add each promise to the myPromises array.
  myPromises.push(myPromise);

}

// We create an html span element and...
let span = document.createElement('span');
span.style.color = '#ffffff';
// We set the element's span text to Please wait...
span.innerText = 'Please wait...';
// We add the span element to the document body.
document.body.append(span);


// Promise.all requires an array.
Promise.all(myPromises).then((myResponses) => {

  // debug
  // console.log(myResponses);

  // We create an html img element and...
  let span = document.createElement('span');
  span.style.color = '#ffffff';
  // We set the element's span text to Please wait...
  span.innerText = 'Done.';
  // We add the span element to the document body.
  document.body.append(span);

  // We create an html img element and...
  let br = document.createElement('br');
  // We add the br element to the document body.
  document.body.append(br);

  // for each promise resolved...
  for(let i = 0; i < myResponses.length; i++) {

    // We check its returned object containing the resolverImg...
    if(myResponses[i].resolverImg !== null) {

      // We create an html img element and...
      let img = document.createElement('img');
      // We set the element's image source to the resolverImg url returned and..
      img.src = myResponses[i].resolverImg;
      // We add the img element to the document body.
      document.body.append(img);

    }

  }

}).catch(err => console.error(err));

// The individual Promise.
// Accepts 5 arguments; image size, background color, foreground color, image file extension, image text.
async function getRandomImage(imgWidth, imgHeight, bgHexColor, fgHexColor, imgExt, imgText) {

  // The Response interface of the Fetch API represents the response to a request.
  // https://developer.mozilla.org/en-US/docs/Web/API/Response

  // We initialize the image and status as null...
  let myResolverImg      = null;
  let myResolverStatus   = null;

  // We use a Try/Catch block to check if the resolverImg exists...
  try {

    // We create a fetch async resolver...
    let myResolver       = await fetch(`https://dummyimage.com/${imgWidth}x${imgHeight}/${bgHexColor}/${fgHexColor}${imgExt}&text=${imgText}`);

    // debug
    // console.log(myResolver);

    if(myResolver.ok) {
      // if it exists, change it from null to a valid image url path.
      myResolverImg      = myResolver.url;
      myResolverStatus   = myResolver.status;
    }

    } catch (err) {
    // if fetch network error...
    console.error('Fetch network error.');
  }

  // Return js object containing image url OR, resolverImg REMAINS null as initially declared.
  return {
       resolverImg: myResolverImg,
    resolverStatus: myResolverStatus
  };

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...