Promise链接和.then / .catch语句

时间:2019-03-08 04:45:48

标签: javascript asynchronous promise es6-promise

以下代码摘自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 个答案:

答案 0 :(得分:2)

您的代码确实出现错误。例如,在Firefox中,它将在开发人员控制台中显示TypeError: r.json is not a function。 (我发现您使用的是alert(),因此您可能不熟悉开发者控制台和浏览器中的console.log()。如果是这样,我建议您参考他们提供的信息是无价的。)

问题在于,在r.json()中,r是响应对象,或者是由于较早的第一个.catch(err=>err)而导致的异常对象。由于异常对象没有json属性,因此它会抛出自己的异常。不会捕获该异常,因为没有try/catch,并且.catch()仅可用于promise。

您可以执行以下操作来检查并传递初始异常:

responses.map(r => r.json ? r.json().catch(err=>err) : r)

答案 1 :(得分:0)

之所以不起作用,是因为在第一个.catch(err=>err)语句中,它将错误视为标准(成功)结果。然后,任何从fetch获取的错误数据都会被调用到下一个Promise.all语句中,因为它被视为良好结果,因此r.json()将不知道如何处理任何错误数据(来自fetch('/ ')。