#javascript #node.js #mongodb #express #promise
#javascript #node.js #mongodb #экспресс #обещание
Вопрос:
Я изучаю Node, Express и Mongodb, следовательно, очень новичок. Я разрабатываю форму, в которой есть текстовое поле, в которое пользователь будет добавлять данные.
Во-первых, мне нужно проверить, существуют ли эти данные или нет в главной таблице. Если существует, то я верну идентификатор записи, иначе я создам новую запись и верну ее идентификатор. Ниже приведен код, который я пробовал, но он выдает мне идентификатор как неопределенный.
code.js (контроллер)
const toolsModel = require('../models/modTools');
const { validationResult } = require('express-validator');
module.exports = {
async saveCode(req, res)
{
var promiseToolId = () => {
return new Promise((resolve, reject) => {
let tool_exist = toolsModel.findOne({ title: req.body.inpTool });
if (tool_exist) {
console.log('tool_exist'); // prints this line
console.log(tool_exist._id); // gives undefined
console.log(tool_exist); // prints the object.
resolve(tool_exist._id);
}
else{
console.log('tool not exist. inserting');
var newTool = new toolsModel();
newTool.insert({title: req.body.inpTool, created_at: new Date()}, function(err, newRec) {
if(err){
console.log('err while inserting');
console.log(err);
reject(err);
}
else{
console.log('inserted');
console.log(newRec);
resolve(newRec._id);
}
});
}
});
};
let errors = validationResult(req);
if (!errors.isEmpty()){
console.log('validation error');
console.log(errors);
}
else{
console.log('form is valid'); // prints this line
// check if the tool exists in our database
var toolId = await (promiseToolId()); //anything here is executed after result is resolved
console.log('toolId ', toolId); // prints undefined
}
}
};
modTools.js (модель)
const mongoose = require('mongoose'),
timeZone = require('mongoose-timezone'),
Schema = mongoose.Schema;
const toolsSchema = new Schema({
title: {type:String, required:true, trim: true},
created_at: {type: Date, default: Date.now},
});
toolsSchema.plugin(timeZone);
module.exports = mongoose.model('developmentTools', toolsSchema);
Пожалуйста, обратите внимание, что я использую идентификатор автоматического увеличения для своей модели, которую я создал, используя приведенные ниже коды.
db.createCollection("developmentTools");
db.developmentTools.insert ( {_id: "toolsId" , toolSeqValue : 0 } );
function getToolsNextID(seqName) {
var seqDoc = db.developmentTools.findAndModify({
query: { _id: seqName },
update: { $inc: { toolSeqValue: 1 } },
new: true
});
return seqDoc.toolSeqValue;
}
Я знаю, как я получаю доступ к свойству объекта tool_exist.title правильно, но не знаю, почему он дает мне undefined.
Я ошибаюсь в реализации обещания?
Пожалуйста, помогите.
С уважением,
Джавед Ансари
Комментарии:
1. вы возвращаете обещание
new Promise
внутриasync / await
функции и даже не используете его.findOne()
. там вы используете какой-то другой подход. вы используете старый подход обратного вызова. существует множество анти-шаблонов, которых следует избегать2. @Ifaruki Я новичок в nodejs. Можете ли вы поделиться со мной некоторыми руководствами, в которых я могу узнать эффективный способ написания кодов в nodejs?
3. здесь stackoverflow.blog/2019/09/12/ … забудьте о «typescript» здесь, вы можете игнорировать его
Ответ №1:
Я могу решить проблему. Перечисление полного кода, если кто-то сталкивается с такой же проблемой. Большое спасибо @ifaruki за предоставление информативного URL-адреса и @slimane-amiar за его время.
async saveCode(req, res)
{
async function createTool(tool_ttle){
var newTool = new toolsModel({
title: tool_ttle,
created_at: new Date()
});
return new Promise((resolve, reject) => {
newTool.save((err, newRec) => {
if(err){
console.log('err while inserting');
reject(err);
}
else{
console.log('inserted');
resolve(newRec);
}
});
});
}
let errors = validationResult(req);
if (!errors.isEmpty()){
console.log('validation error');
console.log(errors);
}
else{
console.log('form is valid');
toolTitle = req.body.inpTool;
toolTitle = toolTitle.trim().toUpperCase();
let toolRecord = '';
// check if the tool exists in our database
try {
toolRecord = await toolsModel.findOne({ title: toolTitle });
if (toolRecord){
console.log('tool_exist');
console.log(toolRecord);
}
else{
console.log('tool not exist. inserting');
toolRecord = await createTool(toolTitle);
if(toolRecord){
console.log('new tool is created below');
console.log(toolRecord);
}
else
{
console.log('error in creating new tool');
console.log(toolRecord);
}
}
}
catch(error){
console.log('in catch');
console.log(error);
return error;
}
console.log('proceeding further');
}
}
Ответ №2:
Вы должны добавить await
к запросу, поскольку он возвращает обещание, как показано ниже
return new Promise( async (resolve, reject) => {
let tool_exist = await toolsModel.findOne({ title: req.body.inpTool });
Комментарии:
1. Спасибо за ваше решение. Попробовал совет ur, но выдает ошибку, поскольку «ожидание допустимо только в асинхронной функции»
2. затем сделайте его асинхронным
return new Promise( async (resolve, reject) => {