Mongoose: Model.create Promesse résolue bien qu'aucun document n'ait été enregistré

Créé le 1 févr. 2018  ·  3Commentaires  ·  Source: Automattic/mongoose

Bonjour à tous,

J'utilise la version 5.0.3 de la mangouste et la version 9.4.0 du nœud. Selon la documentation de la mangouste, model.create devrait renvoyer une promesse qui, je suppose, est résolue lorsque le document créé est enregistré dans la base de données. Cependant, comme le montre le code ci-dessous, il semble que la promesse soit résolue avant que le document ne soit enregistré dans la base de données.

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 ne trouve aucun document. En plus de cela, "created" apparaît à la fin dans le terminal, d'où le rappel de la méthode create est exécuté comme si l'attente n'attendait pas que la tâche asynchrone "create" soit effectuée.

Cependant en ajoutant une promesse qui est résolue une fois le callback de create déclenché, comme indiqué ci-dessous, on obtient le résultat attendu :

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 }

Maintenant, nous avons le résultat attendu.

Toutes les fonctions qui opèrent sur la base de données renvoient une promesse qui, si elle est résolue, indique que l'opération a été effectuée, en particulier Query. Je suppose que c'était également le cas de model.create bien qu'il ne renvoie pas d'objet de requête à proprement parler. Je me demande également ce que signifie la promesse de retour remplie car elle ne montre pas que le document a été créé dans la base de données. J'ai peut-être raté tout le sujet mais je le trouve un peu ambigu

Commentaire le plus utile

Je crois que je me souviens avoir lu dans la documentation 4.x que si vous passez un rappel à model.create, cela ne renvoie pas de promesse.

let x = model.create({ a: 'test' }, () => {})
  x.then(console.log(x)) //TypeError: Cannot read property 'then' of undefined

si vous retirez le rappel :

let x = model.create({ a: 'test' })
  x.then(console.log(x)) // Promise { <pending> }

la source 5.x pour model.js le confirme en appelant utils.promiseOrCallback

Tous les 3 commentaires

Je crois que je me souviens avoir lu dans la documentation 4.x que si vous passez un rappel à model.create, cela ne renvoie pas de promesse.

let x = model.create({ a: 'test' }, () => {})
  x.then(console.log(x)) //TypeError: Cannot read property 'then' of undefined

si vous retirez le rappel :

let x = model.create({ a: 'test' })
  x.then(console.log(x)) // Promise { <pending> }

la source 5.x pour model.js le confirme en appelant utils.promiseOrCallback

Oui , @CodeurSauvage ?

@CodeurSauvage @lineus est correct, pas de promesse si un rappel est spécifié. Votre script fonctionne si vous remplacez :

    await model.create({ a: 'test'}, 
       (err,result)=> {console.log('created');});

Avec:

    await model.create({ a: 'test'}).then(result => console.log('created'));
Cette page vous a été utile?
0 / 5 - 0 notes