Node.js代码只能在文件顶部使用sequelize

当在我的服务器端代码的顶部,这工作正常,产生的结果是正确的:

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方法中时,它运行不正常。 特别是,扩展方法不能正常工作。

 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()调用。

从你的代码我已经进行了,你想要返回播放列表( idname )连同他们的歌曲( id )。 首先,你的代码将无法工作,因为在data_playlists被上面的代码填充数据之前运行addsongs(data_playlists, id)的调用。 而且, addsongs函数执行返回Promises的asynchronous操作,所以一个接一个地调用它们不会给出预期的结果。 我想你可以完全不同的做法。

我build议你使用可以传递给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 } ] } ] 

上面的代码返回所有playlists (他们的idname )与他们的songs (只有他们的id )。 现在在你的路由parsing器中,你可以直接调用上面的函数来返回结果

 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; });