为什么在HTTP请求获取和响应中需要两个Promise.all实例?

时间:2019-04-05 01:14:41

标签: javascript promise

在下面的代码中,我们试图获取几个URL,并在响应返回时处理错误。

我注意到这里使用了2 Promise.all。为什么必须使用第二个Promise.all?删除它会怎样?

Promise.all( //1st one
    urls.map(url => fetch(url).catch(err => err))
  )
  .then(responses => Promise.all( //2nd one
    // if it's an error then pass on
    // otherwise response.json() and catch errors as results
    responses.map(r => r instanceof Error ? r : r.json().catch(err => err))
  ))
  .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)

第二个Promise.all()将所有成功的响应映射到JSON。

由于pb-util本身会返回一个承诺,因此responses.map(...)产生的数组可能看起来像

[ error, Promise<Object>, Promise<Object>, error, Promise<Object> ]

为了等待所有json()的诺言得到解决,您需要使用第二个Promise.all()

数组中的非承诺将被视为Promise.resolve(item)


请注意,此代码可以更简洁地编写(请参阅其他答案)。这个答案更像是“为什么代码是这样的”

答案 1 :(得分:2)

您可以将fetch和json组合在一个链中:

urls = [
    "https://jsonplaceholder.typicode.com/todos/1",
    "http://wtf"
]

Promise.all(
    urls.map(url => 
        fetch(url).then(r => r.json()).catch(String))
).then(console.log)