当在我的服务器端代码的顶部时,这工作正常并且产生的结果是正确的:
var data_playlists = {};
models.Playlist.findAll({
attributes: ['id', 'name']
}).then(function (playlists){
data_playlists['playlists'] = playlists.map(function(playlist){
return playlist.get({plain: true})
});
addsongs(data_playlists, 1);
addsongs(data_playlists, 2);
addsongs(data_playlists, 3);
});
但是当它位于我的 Express 方法之一内时,它无法正常运行;特别是,addsongs 方法无法正常工作。
function addsongs(playlist_object, id_entered){
var arraysongs = [];
models.Playlist.findOne({
attributes: ['id'],
where: {
id: id_entered
}
})
.then(function(playlist) {
playlist.getSongs().then(function (thesongs){
for(var k = 0; k < thesongs.length ; k++){
arraysongs.push(thesongs[k].Songs_Playlists.SongId);
}
playlist_object.playlists[(id_entered - 1)]['songs'] = arraysongs;
});
});
}
我一生都无法弄清楚为什么当代码的顶部片段位于顶部时它可以工作,但在我的 app.get() 调用中却不起作用。
最佳答案
根据您的代码,我发现您想要返回播放列表(id
和 name
)及其歌曲(id
)。首先,您的代码将无法工作,因为 addsongs(data_playlists, id)
的调用是在 data_playlists
通过上面的代码填充数据之前运行的。此外,addsongs 函数执行异步操作并返回 Promises,因此逐一调用它们不会给出预期结果。我想你可以完全不同地做到这一点。
我建议您使用可以传递给 findAll()
方法的 options
对象的 include
属性。 include
表示您还希望从当前查询返回哪个关联模型。在本例中,您希望返回播放列表及其歌曲(根据您的代码,M:M 关系),因此您需要在查询中包含 Song
模型。
function getPlaylistsWithSongs() {
return models.Playlist.findAll({
attributes: ['id', 'name'],
include: [
{
model: models.Song,
as: 'Songs', // depends on how you have declare the association between songs and playlists
attributes: ['id'],
through: { attributes: [] } // prevents returning fields from join table
}
]
}).then((playlistsWithSongs) => {
return playlistsWithSongs;
});
}
getPlaylistsWithSongs
结果的示例结果为(将其转换为 JSON 后,例如 playlistsWithSongs.toJSON()
)
[
{
id: 1,
name: 'playlist #1',
Songs: [
{ id: 1 },
{ id: 2 }
]
}
]
以上代码返回所有播放列表
(其id
和name
)及其歌曲
(仅其 >id
)。现在在您的路由解析器中,您可以简单地调用上面的函数来返回结果
app.get('/api/playlists', function (request, response) {
response.setHeader("Content-Type", "application/json; charset=UTF-8");
getPlaylistsWithSongs().then(function(playlistsWithSongs){
response.status(200).send(JSON.stringify(playlistsWithSongs));
});
});
编辑
为了简单地返回 ID 数组而不是具有 id 的对象数组(songs
),您需要映射结果。在这种情况下,没有简单的 Sequelize 方法可以返回 ID 数组。
}).then((playlistWithSongs) => {
let jsonPlaylists = playlistsWithSongs.map((singlePlaylist) => {
// return JSON representation of each playlist record
return singlePlaylist.toJSON();
});
jsonPlaylists.forEach((playlist) => {
// at every playlist record we map Songs to array of primitive numbers representing it's IDs
playlist.songs = playlist.Songs.map((song) => {
return song.id;
});
// when we finish we can delete the Songs property because now we have songs instead
delete playlist.Songs;
});
console.log(jsonPlaylists);
// example output: [{ id: 1, name: 'playlist #1', songs: [1, 2, 3] }]
return jsonPlaylists;
});
关于javascript - Node.js 代码仅在带有 Sequelize 的文件顶部工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42547052/