多次处理同一个请求
Handle same request multiple times
我正在构建一个用于学习的愚蠢的音乐问答游戏。我需要用 deezer api 中的相关音乐填充我的视图。
我需要的:
- 获取随机类型
- 从该流派中获得 5 位艺术家 (id + name)
- 从每位艺术家那里获得 1 首音乐(姓名 + link 预览)
因此,I found my way 直到第 3 步
但我无法找到如何正确发送相同请求 4 次(针对每个艺术家),而且我的研究到目前为止没有任何结果
function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
fetch(reqGenero)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Erro ao pegar gêneros');
}
})
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetch('https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Erro ao pegar artistas');
}
})
.then(artistas => {
/* 1 música de 4 artistas */
var artistasIds = [];
for(var i = 0; i <= 4; i++) {
artistasIds.push(artistas.data[i].id);
console.log('\nId: ' + artistasIds[i]);
// CAN I SEND THIS REQUEST 4 TIMES?
return fetch('https://api.deezer.com/artist/' + ids + '/top');
}
})
.catch(error => {
console.error(error);
});
}
*如果我做错了什么请告诉我
您可以创建 4 个请求并等待它们全部完成,使用Promise#all。
.then(artistas => {
/* 1 música de 4 artistas */
const artistasPromises = artistas.data.map(artista =>
fetch("https://api.deezer.com/artist/" + artista.id + "/top").catch(
err => ({ error: err })
)
);
return Promise.all(artistasPromises);
}).then(musicList => {
console.log(musicList);
});
注意 catch()
。这样可以确保即使一次提取失败,也不会忽略其他提取结果。这是因为 Promise#all 的工作方式。因此,您需要遍历 musicList
并检查是否存在任何形状为 { error: /* error object */ }
的对象,并在处理列表时忽略它。
你可以替换语句
// CAN I SEND THIS REQUEST 4 TIMES?
return fetch('https://api.deezer.com/artist/' + ids + '/top');
和
const fetchResults = [];
artistasIds.forEach(function(ids){
fetchResults.push(fetch('https://api.deezer.com/artist/' + ids + '/top'));
});
return Promise.all(fetchResults);
在 然后 条件下,您将获得包含每位艺术家的顶级音乐的一系列值。我没有检查给定的 API,但理想情况下它应该可以工作。
是的,您可以提出 5 个请求(不是 4 个,而是 0-4)并等待每个请求完成。
使用 Array.prototype.map 创建请求承诺数组。(优于 for- forEach 和 array.push)
和Promise.all
等待所有承诺完成,如果没有失败,这将 return 已解决响应的数组。
.then(artistas => {
/* 1 música de 4 artistas */
var artistasIds = [];
let ids = artistas.data.map(artist => artist.id).slice(0, 4);
requests = ids.map(id => fetch(`https://api.deezer.com/artist/${id}/top`));
return Promise.all(requests);
}
})
如果明确使用 promises(请参阅下面的 async
函数),我可能会这样处理;请参阅 ***
评论以获取解释:
// *** Give yourself a helper function so you don't repeat this logic over and over
function fetchJson(errmsg, ...args) {
return fetch(...args)
.then(response => {
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
});
}
function deezer() {
// *** Not sure why you're using Request here?
const reqGenero = new Request('https://api.deezer.com/genre');
fetchJson('Erro ao pegar gêneros', reqGenero)
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(artistas => {
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
})
.then(musica => {
// *** Use musica here, it's an array of the music responses
})
.catch(error => {
console.error(error);
});
}
假设您想使用 deezer
中的结果。如果你想要deezer
到return的结果(四首歌的承诺),那么:
// *** Give yourself a helper function so you don't repeat this logic over and over
function fetchJson(errmsg, ...args) {
return fetch(...args)
.then(response => {
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
});
}
function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
return fetchJson('Erro ao pegar gêneros', reqGenero) // *** Note the return
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(artistas => {
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
});
// *** No `then` using the results here, no `catch`; let the caller handle it
}
第二个的 async
功能版本:
// *** Give yourself a helper function so you don't repeat this logic over and over
async function fetchJson(errmsg, ...args) {
const response = await fetch(...args)
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
}
async function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
const generos = await fetchJson('Erro ao pegar gêneros', reqGenero);
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
const artistas = await fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists');
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
}
我正在构建一个用于学习的愚蠢的音乐问答游戏。我需要用 deezer api 中的相关音乐填充我的视图。
我需要的:
- 获取随机类型
- 从该流派中获得 5 位艺术家 (id + name)
- 从每位艺术家那里获得 1 首音乐(姓名 + link 预览)
因此,I found my way 直到第 3 步
但我无法找到如何正确发送相同请求 4 次(针对每个艺术家),而且我的研究到目前为止没有任何结果
function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
fetch(reqGenero)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Erro ao pegar gêneros');
}
})
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetch('https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Erro ao pegar artistas');
}
})
.then(artistas => {
/* 1 música de 4 artistas */
var artistasIds = [];
for(var i = 0; i <= 4; i++) {
artistasIds.push(artistas.data[i].id);
console.log('\nId: ' + artistasIds[i]);
// CAN I SEND THIS REQUEST 4 TIMES?
return fetch('https://api.deezer.com/artist/' + ids + '/top');
}
})
.catch(error => {
console.error(error);
});
}
*如果我做错了什么请告诉我
您可以创建 4 个请求并等待它们全部完成,使用Promise#all。
.then(artistas => {
/* 1 música de 4 artistas */
const artistasPromises = artistas.data.map(artista =>
fetch("https://api.deezer.com/artist/" + artista.id + "/top").catch(
err => ({ error: err })
)
);
return Promise.all(artistasPromises);
}).then(musicList => {
console.log(musicList);
});
注意 catch()
。这样可以确保即使一次提取失败,也不会忽略其他提取结果。这是因为 Promise#all 的工作方式。因此,您需要遍历 musicList
并检查是否存在任何形状为 { error: /* error object */ }
的对象,并在处理列表时忽略它。
你可以替换语句
// CAN I SEND THIS REQUEST 4 TIMES?
return fetch('https://api.deezer.com/artist/' + ids + '/top');
和
const fetchResults = [];
artistasIds.forEach(function(ids){
fetchResults.push(fetch('https://api.deezer.com/artist/' + ids + '/top'));
});
return Promise.all(fetchResults);
在 然后 条件下,您将获得包含每位艺术家的顶级音乐的一系列值。我没有检查给定的 API,但理想情况下它应该可以工作。
是的,您可以提出 5 个请求(不是 4 个,而是 0-4)并等待每个请求完成。 使用 Array.prototype.map 创建请求承诺数组。(优于 for- forEach 和 array.push)
和Promise.all 等待所有承诺完成,如果没有失败,这将 return 已解决响应的数组。
.then(artistas => {
/* 1 música de 4 artistas */
var artistasIds = [];
let ids = artistas.data.map(artist => artist.id).slice(0, 4);
requests = ids.map(id => fetch(`https://api.deezer.com/artist/${id}/top`));
return Promise.all(requests);
}
})
如果明确使用 promises(请参阅下面的 async
函数),我可能会这样处理;请参阅 ***
评论以获取解释:
// *** Give yourself a helper function so you don't repeat this logic over and over
function fetchJson(errmsg, ...args) {
return fetch(...args)
.then(response => {
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
});
}
function deezer() {
// *** Not sure why you're using Request here?
const reqGenero = new Request('https://api.deezer.com/genre');
fetchJson('Erro ao pegar gêneros', reqGenero)
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(artistas => {
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
})
.then(musica => {
// *** Use musica here, it's an array of the music responses
})
.catch(error => {
console.error(error);
});
}
假设您想使用 deezer
中的结果。如果你想要deezer
到return的结果(四首歌的承诺),那么:
// *** Give yourself a helper function so you don't repeat this logic over and over
function fetchJson(errmsg, ...args) {
return fetch(...args)
.then(response => {
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
});
}
function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
return fetchJson('Erro ao pegar gêneros', reqGenero) // *** Note the return
.then(generos => {
/* pega genero aleatorio */
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists')
})
.then(artistas => {
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
});
// *** No `then` using the results here, no `catch`; let the caller handle it
}
第二个的 async
功能版本:
// *** Give yourself a helper function so you don't repeat this logic over and over
async function fetchJson(errmsg, ...args) {
const response = await fetch(...args)
if (!response.ok) { // *** .ok is simpler than .status == 200
throw new Error(errmsg);
}
return response.json();
}
async function deezer() {
const reqGenero = new Request('https://api.deezer.com/genre');
const generos = await fetchJson('Erro ao pegar gêneros', reqGenero);
var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id;
//console.log('\ngenero... ' + generoId);
const artistas = await fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists');
/* 1 música de 4 artistas */
// *** Use Promise.all to wait for the four responses
return Promise.all(artistas.data.slice(0, 4).map(
entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top')
));
}