Javascript 循环从节点promise返回的对象,并将其馈送到下一个
我一直被这个问题困扰着,这似乎是一个永恒的问题。 我刚进入节点,开始思考承诺等问题 我想做的是从Spotify API获取数据,我要做的第一件事是获取自己的播放列表:Javascript 循环从节点promise返回的对象,并将其馈送到下一个,javascript,node.js,promise,Javascript,Node.js,Promise,我一直被这个问题困扰着,这似乎是一个永恒的问题。 我刚进入节点,开始思考承诺等问题 我想做的是从Spotify API获取数据,我要做的第一件事是获取自己的播放列表: function getPlaylists(access_token) { var options = { url: 'https://api.spotify.com/v1/me/playlists', headers: { 'Authorization': 'Bearer ' + access_
function getPlaylists(access_token) {
var options = {
url: 'https://api.spotify.com/v1/me/playlists',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
return new Promise(function(resolve, reject) {
request.get(options, function(error, response, body) {
var playlists = body.items;
var playlistArray = [];
playlists.forEach(function(playlist) {
var name = playlist.name;
var url = playlist.tracks.href;
playlistArray.push(url);
});
if(!error) {
resolve(playlistArray);
} else {
reject(error);
}
});
});
}
function getArtists(url,access_token) {
var params = {
url: url,
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
return new Promise(function(resolve, reject) {
request.get(params, function(error, response, body) {
var tracks = body.items;
var artistArray = [];
tracks.forEach(function(artists) {
let allArtists = artists.track.artists;
allArtists.forEach(function(artist) {
artistArray.push(artist);
});
})
if(!error) {
resolve(artistArray);
} else {
reject(error);
}
});
})
}
好的,到目前为止还不错。现在我还想从这些播放列表中找到艺术家:
function getPlaylists(access_token) {
var options = {
url: 'https://api.spotify.com/v1/me/playlists',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
return new Promise(function(resolve, reject) {
request.get(options, function(error, response, body) {
var playlists = body.items;
var playlistArray = [];
playlists.forEach(function(playlist) {
var name = playlist.name;
var url = playlist.tracks.href;
playlistArray.push(url);
});
if(!error) {
resolve(playlistArray);
} else {
reject(error);
}
});
});
}
function getArtists(url,access_token) {
var params = {
url: url,
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
return new Promise(function(resolve, reject) {
request.get(params, function(error, response, body) {
var tracks = body.items;
var artistArray = [];
tracks.forEach(function(artists) {
let allArtists = artists.track.artists;
allArtists.forEach(function(artist) {
artistArray.push(artist);
});
})
if(!error) {
resolve(artistArray);
} else {
reject(error);
}
});
})
}
我返回所有这些数据的方式是:
getPlaylists(access_token)
.then(function(playlists) {
playlists.forEach(function(playlist) {
getArtists(playlist,access_token)
.then(function(artist) {
return artist;
});
});
}).then(function(artists) {
console.log("getting artists",artists);
}).catch(function(error) {
console.log(error);
})
但是,这返回未定义的。只有将一个播放列表url传递给getArtists函数,我才能使它工作——问题是forEach循环,我不知道如何处理它
非常感谢您的帮助 您可以结合使用
[].map()
和Promise.all()
来做出承诺,等待一系列操作完成:
getPlaylists(access_token)
.then(playlists => Promise.all(playlists.map(playlist =>
getArtists(playlist, access_token)))
.then(artists => {
// use here
});
请记住,对于要链接的承诺,必须从处理程序返回值或承诺.forEach()
始终返回未定义的
,无论发生什么情况
首先,我们使用.map()
和getArtist
将播放列表数组转换为承诺数组,然后将该承诺数组传递给Promise.all()
,该数组返回单个承诺,该承诺在数组中的所有承诺都解决时解决(或在第一个承诺被拒绝时拒绝).你的承诺不是承诺,因此你也不会兑现承诺。如果你使用蓝鸟承诺,它有一个Promise.map。用这个替换你的forEach,并确保你返回了这样的Promise.map,你应该准备好了。奇怪的是,在阅读了大量关于promises的文章后,你的代码示例终于让它点击了。