Mongoose: Model.create Promise разрешен, хотя документ не сохранен

Созданный на 1 февр. 2018  ·  3Комментарии  ·  Источник: Automattic/mongoose

Всем привет,

Я использую версию 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

Все 3 Комментарий

Думаю, я помню, как читал в документах 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'));
Была ли эта страница полезной?
0 / 5 - 0 рейтинги