Я довольно новичок в JS и создаю веб-приложение с рекомендациями mov ie, используя express и neo4j. Я столкнулся с проблемами при запуске метода объекта для маршрута. По сути, я создал объект Genre и вызвал метод для получения списка популярных фильмов, указав c для этого жанра, который я затем перенаправляю в представления.
Я использую asyn c и ожидаю обработки асинхронных вызовов, и я протестировал каждый модуль отдельно, и они работают как положено.
У меня есть два класса, относящихся к этой проблеме - Mov ie и Genre, а также маршрут для обработки запросов.
Модуль жанра:
const executeQuery = require('./db/Neo4jApi').executeQuery;
const Movie = require('./Movie');
module.exports = class Genre {
constructor(name) {
this.name = name;
}
async getPopularMovies(limit) {
const response = await executeQuery(
'MATCH(:Genre { name: $name })<-[:IN_GENRE]-(m :Movie)<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ name: this.name, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
static getGenreList(names) {
const genres = [];
names.forEach(name => genres.push(new Genre(name)));
return genres;
}
static async getAllGenres() {
const response = await executeQuery(
'MATCH (g:Genre) return collect (g.name)'
);
return Genre.getGenreList(response.records[0]._fields[0]);
}
static async test() {
const action = new Genre('Animation');
console.log(await action.getPopularMovies(5));
console.log(Genre.getGenreList(["Action", "Crime", "Thriller"]));
}
}
Модуль Mov ie:
const executeQuery = require('./db/Neo4jApi').executeQuery;
const Person = require('./Person');
const Genre = require('./Genre');
module.exports = class Movie {
constructor(id) {
this.id = id;
}
setPoster() {
let poster_id = "";
for (var i = 0; i < this.id.length; i++) {
if (this.id[i] != '0') {
poster_id = this.id.substring(i);
break;
}
}
this.poster = '/images/' + poster_id + '.jpg';
}
// set details of given imdbid to build object
async getDetails() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})\
RETURN m.title, m.runtime, m.year, m.plot, m.poster',
{ id: this.id }
);
const fields = response.records[0]._fields;
this.title = fields[0];
this.runtime = fields[1].low;
this.year = fields[2].low;
this.plot = fields[3];
this.setPoster();
}
// return list of movie objects corresponding the given list of imdbIds
// THIS IS THE METHOD THAT IS NOT BEING RECOGNIZED
static async getMovieList(ids) {
const movies = [];
ids.forEach(id => movies.push(new Movie(id)));
for (const movie of movies) await movie.getDetails();
return movies;
}
// return list of genres of movie
async getGenre() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})-[:IN_GENRE]->(g:Genre)\
RETURN collect(g.name)',
{ id: this.id }
);
return Genre.getGenreList(response.records[0]._fields[0]);
}
// returns average rating of movie (out of 5)
async getAvgRating() {
const response = await executeQuery(
'MATCH (:Movie {imdbId : $id})<-[r:RATED]->(:User)\
RETURN AVG(r.rating)',
{ id: this.id }
);
return response.records[0]._fields[0].toFixed(2);
}
// return director/s of movie
async getDirector() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})<-[:DIRECTED]-(d:Director)\
RETURN collect(d.name)',
{ id: this.id }
);
return Person.getPersonList(response.records[0]._fields[0]);
}
// returns cast of movie
async getCast() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})<-[:ACTED_IN]-(a:Actor)\
RETURN collect(a.name)',
{ id: this.id }
);
return Person.getPersonList(response.records[0]._fields[0]);
}
// returns movies similar to this movie
async getSimilar(limit) {
const response = await executeQuery(
'MATCH (curr :Movie { imdbId: $id })-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(sim :Movie)\
WITH curr, sim, COUNT(*) AS commonGenres\
OPTIONAL MATCH(curr)<-[: DIRECTED]-(d:Director)-[:DIRECTED]-> (sim)\
WITH curr, sim, commonGenres, COUNT(d) AS commonDirectors\
OPTIONAL MATCH(curr)<-[: ACTED_IN]-(a: Actor)-[:ACTED_IN]->(sim)\
WITH curr, sim, commonGenres, commonDirectors, COUNT(a) AS commonActors\
WITH sim.imdbId AS id, (3 * commonGenres) + (5 * commonDirectors) + (2 * commonActors) AS Similarity\
ORDER BY Similarity DESC\
LIMIT $limit\
RETURN collect(id)',
{ id: this.id, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
// returns all time popular movie
static async getPopularMovies(limit) {
const response = await executeQuery(
'MATCH (m :Movie)<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
// returns popular movies of given year
static async getPopularMoviesByYear(year, limit) {
const response = await executeQuery(
'MATCH(m :Movie {year : $year})<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ year, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
static async getYears() {
const response = await executeQuery(
'MATCH (m:Movie)\
WITH DISTINCT m.year AS year ORDER BY year DESC\
RETURN COLLECT(year)'
);
return response.records[0]._fields[0];
}
static async test() {
}
}
Маршрут:
const express = require('express');
const router = express.Router();
const Genre = require('../models/Genre');
const Movie = require('../models/Movie');
// get popular movies by all genre
router.get('/', async (req, res) => {
const allGenrePopular = await Movie.getPopularMovies(25);
const genres = await Genre.getAllGenres();
res.render('genre-list', {
title: 'All Genres',
header: 'Popular Movies: All Genres',
movies: allGenrePopular,
genres
});
});
// get popular movies by genre
router.get('/:genre?', async (req, res) => {
const genre = new Genre(req.params.genre);
const popularMovies = await genre.getPopularMovies(25);// error originated here
const genres = await Genre.getAllGenres();
res.render('genre-list', {
title: `${genre.name}`,
header: `Popular Movies: ${genre.name}`,
movies: popularMovies,
genres
});
});
module.exports = router;
Но я продолжаю получать эту ошибку:
(node:10272) UnhandledPromiseRejectionWarning: TypeError: Movie.getMovieList is not a function
at Genre.getPopularMovies (C:\Users\Admin\Desktop\project\newmd\models\Genre.js:19:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:10272) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10272) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
Проблема возникает в функции getMovieList () в модуле mov ie, но я проверял ее отдельно и это прекрасно работает.
Любые предложения по улучшению моего кода приветствуются.