我目前正在学习async await fetch
,并且创建了以下示例来帮助我学习。
下面的工作示例:
url
中提取json
img
元素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();
答案 0 :(得分:4)
使用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 :(得分:1)
@suchislife:老实说,您发布的答案应该是一个单独的问题。我已将其标记出来,因为它实际上是一个单独的问题。这与您最初关于获取undefined
的问题无关。我仅在此处发布此内容以临时回答您的问题,但是您应该接受escapello的回答,这应该是不同的主题。允许这样的事情会使StackOverflow混乱。
@Moderators:实际上,我刚才注意到@suchislife提到了处理404,但从未明确声明或在您的代码中表明您的目标是捕获404错误,而您的问题是关于一个单独的错误。我不确定应该如何对待。我猜这是问题的一部分吗?
.error和try / catch不是您要的内容:
fetch resolves even if 404?
您需要检查response.ok
的值。提取只会在网络问题上引发错误,而不是错误响应。
// 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
};
}