Promise 不会 return 有效值
Promise wont return valid value
我做了这个测试只是为了检查 API,但后来我尝试从第二次提取中添加一个 URL,使用在第一次提取中获得的值作为参数,然后 return 要在第一个 fecth 中添加的值。这个想法是将图像 URL 添加到 link。提前致谢。
function script() {
const url = 'https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20'
const result = fetch(url)
.then( (res)=>{
if(res.ok) {
return res.json()
} else {
console.log("Error!!")
}
}).then( data => {
console.log(data)
const main = document.getElementById('main');
main.innerHTML=`<p><a href='${data.next}'>Next</a></p>`;
for(let i=0; i<data.results.length;i++){
main.innerHTML=main.innerHTML+`<p><a href=${getImageURL(data.results[i].url)}>${data.results[i].name}</a></p>`;
}
})
}
async function getImageURL(imgUrl) {
const resultImg = await fetch(imgUrl)
.then( (res)=> {
return res.json()
})
.then (data => {
console.log(data.sprites.other.dream_world.front_default);
})
return resultImg.sprites.other.dream_world.front_default;
}
一般来说,不要将 .then
/.catch
处理程序与 async
/await
混合使用。通常没有必要,它会像这样把你绊倒。
问题是您的履行处理程序(.then
回调)没有 return 任何东西,因此它创建的承诺由 undefined
履行。
你可以 return data
,但实际上根本不使用 .then
/.catch
:
async function getImageURL(imgUrl) {
const res = await fetch(imgUrl);
if (!res.ok) {
throw new Error(`HTTP error ${res.status}`);
}
const resultImg = await res.json();
return resultImg.sprites.other.dream_world.front_default;
}
[注意我添加了 res.ok
的检查。这是(恕我直言)fetch
API 中的一个 footgun,它不会拒绝其对 HTTP 错误(如 404 或 500)的承诺,仅在 网络 上错误。您必须明确检查 HTTP 错误。 (我把它写在我贫血的旧博客上 here。)]
还有一个问题,你使用 getImageURL
:
// Incorrent
for (let i = 0; i < data.results.length; i++) {
main.innerHTML=main.innerHTML+`<p><a href=${getImageURL(data.results[i].url)}>${data.results[i].name}</a></p>`;
}
这里的问题是 getImageURL
,像所有 async
函数一样,return 是一个 承诺 。您正在尝试使用它,因为它 return 提供了您期望的履行价值,但它不能——它还没有那个价值。
相反,您需要等待您在该循环中创建的承诺得到履行。由于该循环是在同步代码中(不是 async
函数),我们将返回到 .then
/.catch
,并且因为我们想等待一组事情完成可以并行完成,我们会用 Promise.all
:
// ...
const main = document.getElementById('main');
const html = `<p><a href='${data.next}'>Next</a></p>`;
Promise.all(data.results.map(async ({url, name}) => {
const realUrl = await getImageURL(url);
return `<p><a href=${realUrl}>${name}</a></p>`;
}))
.then(paragraphs => {
html += paragraphs.join("");
main.innerHTML = html;
})
.catch(error => {
// ...handle/report error...
});
首先,您的
.then (data => {
console.log(//...
在承诺链的末尾 returns 未定义。只需删除它,如果你想 console.log
它,请在 await
.
之后的下一个 statement/next 行中执行 console.log(resultImg)
这是完成我的目标的最终版本。只是想留下这个以防万一有人发现它有用。感谢回答的人!
function script() {
const url = 'https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20'
const result = fetch(url)
.then( (res)=>{
if(res.ok) {
return res.json()
} else {
console.log("Error!!")
}
}).then( data => {
console.log(data)
const main = document.getElementById('main');
main.innerHTML=`<p><a href='${data.next}'>Proxima Página</a></p>`;
Promise.all(data.results.map(async ({url, name}) => {
const realUrl = await getImageURL(url);
return `<div><a href=${realUrl}>${name}</a></div>`;
}))
.then(paragraphs => {
main.innerHTML=main.innerHTML+paragraphs;
})
.catch(error => {
console.log(error);
});
})
}
async function getImageURL(imgUrl) {
const res = await fetch(imgUrl);
if(!res.ok) {
throw new Error(`HTTP Error ${res.status}`)
}
const resultImg = await res.json();
return resultImg.sprites.other.dream_world.front_default
}
我做了这个测试只是为了检查 API,但后来我尝试从第二次提取中添加一个 URL,使用在第一次提取中获得的值作为参数,然后 return 要在第一个 fecth 中添加的值。这个想法是将图像 URL 添加到 link。提前致谢。
function script() {
const url = 'https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20'
const result = fetch(url)
.then( (res)=>{
if(res.ok) {
return res.json()
} else {
console.log("Error!!")
}
}).then( data => {
console.log(data)
const main = document.getElementById('main');
main.innerHTML=`<p><a href='${data.next}'>Next</a></p>`;
for(let i=0; i<data.results.length;i++){
main.innerHTML=main.innerHTML+`<p><a href=${getImageURL(data.results[i].url)}>${data.results[i].name}</a></p>`;
}
})
}
async function getImageURL(imgUrl) {
const resultImg = await fetch(imgUrl)
.then( (res)=> {
return res.json()
})
.then (data => {
console.log(data.sprites.other.dream_world.front_default);
})
return resultImg.sprites.other.dream_world.front_default;
}
一般来说,不要将 .then
/.catch
处理程序与 async
/await
混合使用。通常没有必要,它会像这样把你绊倒。
问题是您的履行处理程序(.then
回调)没有 return 任何东西,因此它创建的承诺由 undefined
履行。
你可以 return data
,但实际上根本不使用 .then
/.catch
:
async function getImageURL(imgUrl) {
const res = await fetch(imgUrl);
if (!res.ok) {
throw new Error(`HTTP error ${res.status}`);
}
const resultImg = await res.json();
return resultImg.sprites.other.dream_world.front_default;
}
[注意我添加了 res.ok
的检查。这是(恕我直言)fetch
API 中的一个 footgun,它不会拒绝其对 HTTP 错误(如 404 或 500)的承诺,仅在 网络 上错误。您必须明确检查 HTTP 错误。 (我把它写在我贫血的旧博客上 here。)]
还有一个问题,你使用 getImageURL
:
// Incorrent
for (let i = 0; i < data.results.length; i++) {
main.innerHTML=main.innerHTML+`<p><a href=${getImageURL(data.results[i].url)}>${data.results[i].name}</a></p>`;
}
这里的问题是 getImageURL
,像所有 async
函数一样,return 是一个 承诺 。您正在尝试使用它,因为它 return 提供了您期望的履行价值,但它不能——它还没有那个价值。
相反,您需要等待您在该循环中创建的承诺得到履行。由于该循环是在同步代码中(不是 async
函数),我们将返回到 .then
/.catch
,并且因为我们想等待一组事情完成可以并行完成,我们会用 Promise.all
:
// ...
const main = document.getElementById('main');
const html = `<p><a href='${data.next}'>Next</a></p>`;
Promise.all(data.results.map(async ({url, name}) => {
const realUrl = await getImageURL(url);
return `<p><a href=${realUrl}>${name}</a></p>`;
}))
.then(paragraphs => {
html += paragraphs.join("");
main.innerHTML = html;
})
.catch(error => {
// ...handle/report error...
});
首先,您的
.then (data => {
console.log(//...
在承诺链的末尾 returns 未定义。只需删除它,如果你想 console.log
它,请在 await
.
console.log(resultImg)
这是完成我的目标的最终版本。只是想留下这个以防万一有人发现它有用。感谢回答的人!
function script() {
const url = 'https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20'
const result = fetch(url)
.then( (res)=>{
if(res.ok) {
return res.json()
} else {
console.log("Error!!")
}
}).then( data => {
console.log(data)
const main = document.getElementById('main');
main.innerHTML=`<p><a href='${data.next}'>Proxima Página</a></p>`;
Promise.all(data.results.map(async ({url, name}) => {
const realUrl = await getImageURL(url);
return `<div><a href=${realUrl}>${name}</a></div>`;
}))
.then(paragraphs => {
main.innerHTML=main.innerHTML+paragraphs;
})
.catch(error => {
console.log(error);
});
})
}
async function getImageURL(imgUrl) {
const res = await fetch(imgUrl);
if(!res.ok) {
throw new Error(`HTTP Error ${res.status}`)
}
const resultImg = await res.json();
return resultImg.sprites.other.dream_world.front_default
}