Цепочки обещаний и .then / .catch - PullRequest
1 голос
/ 08 марта 2019

Следующий код взят из последнего задания https://javascript.info/promise-api.

Когда я запускаю следующее, я не могу получить выходные данные, соответствующие оповещениям, которые указывают комментарии.Я предполагаю, что мне не хватает что-то в выражениях catch, но я не понимаю, где я иду не так.Я ценю любую помощь!

// the whole promise chain fails with an error here
// change that:
// make errors appear as members of the results array

let urls = [
  'https://api.github.com/users/iliakan',
  // this URL is HTML page, it's invalid JSON, so response.json() fails
  '/',
  // this URL is invalid, so fetch fails
  'http://no-such-url'
];

// Fix it:
Promise.all(urls.map(url => fetch(url).catch(err=>err)))
  .then(responses => Promise.all(
    responses.map(r => r.json().catch(err=>err))
  ))
  // Demo output (no need to change):
  .then(results => {
    alert(results[0].name); // Ilya Kantor
    alert(results[1]); // SyntaxError: Unexpected token < in JSON at position 0
    alert(results[2]); // TypeError: failed to fetch (text may vary)
  });

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

Вы получаете ошибку из своего кода. Например, в Firefox в консоли разработчика будет указано TypeError: r.json is not a function. (Я вижу, что вы используете alert(), поэтому вы, возможно, не знакомы с консолью разработчика и console.log(), доступными в браузерах. Если это так, я бы посоветовал обратиться к ним, поскольку информация, которую они предоставляют, может быть неоценимой. )

Проблема в том, что в r.json(), r является либо объектом ответа, либо объектом исключения из-за более раннего, первого .catch(err=>err). Поскольку объекты исключений не имеют свойства json, он генерирует собственное исключение. Это исключение не обнаружено, поскольку для него нет try/catch, а .catch() можно использовать только для обещаний.

Вы можете сделать что-то вроде этого, чтобы проверить и передать начальное исключение:

responses.map(r => r.json ? r.json().catch(err=>err) : r)
0 голосов
/ 08 марта 2019

Причина, по которой это не работает, заключается в том, что в первом операторе .catch(err=>err) он обрабатывает ошибки как стандартный (успешный) результат.Затем любые ошибочные данные из fetch вызываются в следующую инструкцию Promise.all, поскольку они рассматриваются как хороший результат, и, таким образом, r.json () не будет знать, что делать с какими-либо ошибочными данными (которые получены из fetch ('/«).

...