Всем привет,
Я использую версию 5.0.3 мангуста и версию узла 9.4.0. Согласно документации мангуста, model.create должен возвращать обещание, которое, как я полагаю, разрешается, поскольку созданный документ сохраняется в БД. Однако, как показано в приведенном ниже коде, кажется, что обещание выполняется до того, как документ будет сохранен в БД.
async function test(){
let schema = new mongoose.Schema({a: String});
let model = mongoose.model('test', schema);
await model.remove({}).exec();
await model.create({ a: 'test'},
(err,result)=> {console.log('created');});
await model.findOneAndUpdate(
{ a : 'test' } ,
{ a: 'newValue'}
)
.exec((err, result) => {
console.log('update : '+result);
});
await model.find({a: 'test'},(err,result) => {
console.log(result);
});
}
output in terminal :
update : null
found :
created
findOneAndUpdate не находят никаких документов. В дополнение к тому, что «created» появляется в конце терминала, поэтому обратный вызов метода create выполняется так, как если бы ожидание не ожидало выполнения асинхронной задачи «create».
Однако, добавляя обещание, которое разрешается после запуска обратного вызова create, как показано ниже, мы получаем ожидаемый результат:
async function test(){
let schema = new mongoose.Schema({a: String});
let model = mongoose.model('test', schema);
await model.remove({}).exec();
await new Promise((resolve,reject) => {
model.create({ a: 'test'},
(err,result)=> {
console.log('created');
resolve();
});
});
await model.findOneAndUpdate(
{ a : 'test' } ,
{ a: 'newValue'}
)
.exec((err, result) => {
console.log('update : '+result);
});
await model.find({a: 'newValue'},(err,result) => {
console.log('found : ' +result);
});
}
output in terminal:
created
update : { _id: 5a735fbc1fe826233014d62d, a: 'test', __v: 0 }
found : { _id: 5a735fbc1fe826233014d62d, a: 'newValue', __v: 0 }
Теперь у нас есть ожидаемый результат.
Все функции, которые работают с БД, действительно возвращают обещание, которое, если оно разрешено, указывает на то, что операция была выполнена, в частности, Query. Я предполагаю, что это было также в случае с model.create, хотя, строго говоря, он не возвращает объект запроса. Мне также интересно, что означает выполненное возвращенное обещание, поскольку оно не показывает, что документ был создан в БД. Возможно, я упустил всю суть, но я нахожу это немного двусмысленным
Думаю, я помню, как читал в документах 4.x, что если вы передадите обратный вызов в model.create, он не вернет обещание.
let x = model.create({ a: 'test' }, () => {})
x.then(console.log(x)) //TypeError: Cannot read property 'then' of undefined
если вытащить обратный вызов:
let x = model.create({ a: 'test' })
x.then(console.log(x)) // Promise { <pending> }
источник 5.x для model.js несет это, вызывая utils.promiseOrCallback
Да, @lineus правильный, могу ли я закрыть эту проблему @CodeurSauvage ?
@CodeurSauvage @lineus верен, mongoose 5 не возвращает обещание, если указан обратный вызов. Ваш скрипт работает, если вы замените:
await model.create({ a: 'test'},
(err,result)=> {console.log('created');});
С участием:
await model.create({ a: 'test'}).then(result => console.log('created'));
Самый полезный комментарий
Думаю, я помню, как читал в документах 4.x, что если вы передадите обратный вызов в model.create, он не вернет обещание.
если вытащить обратный вызов:
источник 5.x для model.js несет это, вызывая utils.promiseOrCallback