在下面的代码中,我们试图获取几个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)
});
答案 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)