[英]How can I get additional data from one promise to another?
我有一个承诺依赖于另一个承诺的返回值。 我成功地将该值传递给第二个承诺,但是在第一个承诺中创建了额外的数据,我想以某种方式进入第二个承诺。
这是我的代码:
const getAlbumInfo = async (album, artist) => {
let hostname = 'http://www.musicbrainz.org';
let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
let res = await fetch(hostname + path);
return res.json();
};
const getAlbumArt = async (albumInfo) => {
let res = await fetch(`${albumInfo.url}`);
return res.json();
};
let artist = '', album = '';
getAlbumInfo(album, artist)
.then((res) => {
const metadata = {
album: res['album'],
artist: res['artist'],
url: res['url']
};
return getAlbumArt(metadata);
})
.then((res) => {
console.log(res); // prints result from getAlbumArt
// I also need the contents of metadata here
})
.catch(e => { console.error(e); });
所以我在第一个承诺中获取专辑元数据,其中包括一个 URL,然后我在该 URL 上运行一个获取,它返回第二个承诺。 问题是我需要访问第二个承诺中的专辑元数据。
由于我将元数据返回/传递到第二个承诺中,我尝试在getAlbumArt()
使用Object.assign()
getAlbumArt()
来组合元数据和获取结果,但这似乎不起作用。
有多种方法可以做到这一点,您可以使用await
:
const getAlbumInfo = async(album, artist) => {
let hostname = 'http://www.musicbrainz.org';
let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
let res = await fetch(hostname + path);
return res.json();
};
const getAlbumArt = async(albumInfo) => {
let res = await fetch(`${albumInfo.url}`);
return res.json();
};
let artist = '',
album = '';
const getAll = async() => {
const res1 = await getAlbumInfo(album, artist);
const metadata = {
album: res['album'],
artist: res['artist'],
url: res['url']
};
const res2 = await getAlbumArt(metadata);
// here you have access to both responses (res1 and res2) and the created metadata object.
}
如果您使用它,您应该将调用包装在try..catch..
。
另一种选择是将第二个承诺中的元数据与响应一起传递:
const getAlbumInfo = async(album, artist) => {
let hostname = 'http://www.musicbrainz.org';
let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
let res = await fetch(hostname + path);
return res.json();
};
const getAlbumArt = async(albumInfo) => {
let res = await fetch(`${albumInfo.url}`);
res = await res.json();
return {
res,
albumInfo
};
};
let artist = '',
album = '';
getAlbumInfo(album, artist)
.then((res) => {
const metadata = {
album: res['album'],
artist: res['artist'],
url: res['url']
};
return getAlbumArt(metadata);
})
.then((o) => {
console.log(o.res, o.albumInfo);
})
.catch(e => {
console.error(e);
});
第三个选项是在第一个承诺的回调函数中解析第二个承诺:
getAlbumInfo(album, artist)
.then((res) => {
const metadata = {
album: res['album'],
artist: res['artist'],
url: res['url']
};
getAlbumArt(metadata)
.then(res2 => {
// here you can access res, res2 and metadata
})
.catch(..);
})
.catch(..);
由于您可以使用async/await
,我们也可以使用它来解决问题。 最好使用async/await
来保持一致,而不是将它与 Promise 混合使用。
为此,我们需要IIFE
(async () => { // define IIFE
try { // try-catch to ensure error is catched
const res = await getAlbumInfo(album, artist);
const metadata = {
album: res["album"],
artist: res["artist"],
url: res["url"]
};
const res2 = await getAlbumArt(metadata);
console.log(res2);
console.log(metadata);
} catch (error) {
console.error(error);
}
})();
希望能帮助到你
await
第二个承诺,然后将两者都返回到下一个.then
块。 将解构用于更简单的用例:
getAlbumInfo(album, artist)
.then(async ({album, artist, url}) => {
const metadata = {album, artist, url};
const arts = await getAlbumArt(metadata);
return {arts, metadata};
})
.then(({arts, metadata}) => {
// You have both here
})
.catch(console.log);
或者,这整个操作可以在async
函数中:
const getAlbum = async (album, artist) => {
const info = await getAlbumInfo(album, artist);
const metadata = {
album: info.album,
artist: info.artist,
url: info.url,
};
const arts = await getAlbumArt(metadata);
// everything is available;
};
您可以在内部承诺中使用 then 并在那里返回您想要的任何格式的数据。
getAlbumInfo(album, artist)
.then((res) => {
const metadata = {
album: res['album'],
artist: res['artist'],
url: res['url']
};
return getAlbumArt(metadata).then(responseArt => {
return {
innerPromise: responseArt,
outerPromise: metadata
};
});
})
.then((res) => {
console.log(res); // Now u have both here
// I also need the contents of metadata here
})
.catch(e => { console.error(e); });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.