#next.js
#next.js
Вопрос:
Я следовал этому примеру на официальной странице NextJS на Github, и мне удалось запустить свой проект.
Ниже приведена моя файловая структура:
📦pages
┣ 📂api
┃ ┣ 📂auth
┃ ┃ ┣ 📜load.ts
┃ ┃ ┣ 📜login.ts
┃ ┃ ┗ 📜register.ts
┃ ┣ 📂contact
┃ ┃ ┗ 📜index.ts
┃ ┣ 📂listings
┃ ┃ ┣ 📜paginate.ts
┃ ┃ ┣ 📜index.ts
┣ 📜_app.tsx
┣ 📜_document.tsx
┣ 📜_error.tsx
┗ 📜index.tsx
Большинство из этих маршрутов api выполняются await connectDb()
перед продолжением. Вот оно:
import mongoose from 'mongoose';
import config from 'config';
const connectionObject: any = {};
const connectDb = async () => {
if (connectionObject.isConnected) {
return;
}
try {
const db = await mongoose.connect(process.env.MONGODB_URI || config.get('mongoURI'), {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
});
connectionObject.isConnected = db.connections[0].readyState;
} catch (err) {
console.log('Failed to connect to db', err);
}
};
export default connectDb;
Однако проблема, с которой я сталкиваюсь прямо сейчас, заключается в том, что connectionObject
по какой-то причине, похоже, освобождается, когда используются разные маршруты.
Я не могу быть уверен, но я думаю, что до тех пор, пока маршрут, который был выбран, находится в том же каталоге, что и предыдущий маршрут, который был выбран до него, тогда соединение не будет восстановлено. Итак, если я нажимаю login.ts
после нажатия paginate.ts
, будет создано новое соединение с MongoDB. Аналогично, если я нажму load.ts
после login.ts
, новое соединение НЕ будет создано.
Я чувствую, что мне не хватает чего-то элементарного здесь. Какие у меня варианты / что я делаю не так?
Я обнаружил аналогичную проблему с Github, которая, похоже, имеет отношение к моей проблеме, но мне это не помогло.
Комментарии:
1. попробуйте использовать пул соединений? редактировать: неважно, я вижу, что вы ищете сейчас
Ответ №1:
Каждый маршрут API является лямбдой, поэтому каждый из них имеет свое собственное состояние
Комментарии:
1. Я изменил
connectDb
функцию на обычную, но это ничего не исправило. Кажется, что каждый маршрут по-прежнему имеет свое собственное состояние2. @MikeK это не то, что я имею в виду. Вы можете представить каждый маршрут API (файл) как сервер. таким образом, наличие двух маршрутов API похоже на запуск двух серверов, каждый из которых имеет свое собственное глобальное состояние
3. Я понимаю, но возможно ли это как-то исправить? Я использовал пользовательский сервер вместо их pages API, но мне не удалось развернуть его в Vercel таким образом. Развертывание в Vercel поддерживается, только если я использую их встроенный pages API, но недостатком здесь является то, что каждый файл имеет свое собственное состояние, как вы говорите. Итак, какие у меня есть варианты здесь?
4. @MikeK лучше всего использовать другую платформу, такую как Heroku. Но если вы все еще хотите использовать Vercel, вы можете создать специальный маршрут API, который будет содержать ваши состояния, и вы можете отправлять к нему запросы с других маршрутов, чтобы получить эти состояния или обновить их
Ответ №2:
TLDR; consts имеют область действия блока.(connectionObject)
Согласно документации Mozilla const, константы ограничены областью блоков, так же как переменные, определенные с помощью ключевого слова let . Значение константы не может быть изменено путем переназначения, и его нельзя повторно объявить
Итак, в вашем случае connectionObject остается пустым, потому что это область изменения, в которой вы обновляете этот блок. Следовательно, за пределами блока он пуст.
Лучший пример для проверки — первый фрагмент кода в приведенной выше документации
const number = 42;
try {
number = 99;
} catch (err) {
console.log(err);
// expected output: TypeError: invalid assignment to const `number'
// Note - error messages will vary depending on browser
}
console.log(number);
// expected output: 42