Mongoose: Model.create Promise wurde gelöst, obwohl kein Dokument gespeichert wurde

Erstellt am 1. Feb. 2018  ·  3Kommentare  ·  Quelle: Automattic/mongoose

Hallo alle zusammen,

Ich verwende die Mungoversion 5.0.3 und die Knotenversion 9.4.0. Laut Mongoose-Dokumentation sollte model.create ein Promise zurückgeben, das, wie ich annehme, aufgelöst wird, wenn das erstellte Dokument in der DB gespeichert wird. Wie der folgende Code zeigt, scheint die Zusage jedoch aufgelöst zu sein, bevor das Dokument in der Datenbank gespeichert wird.

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 findet kein Dokument. Außerdem wird im Terminal am Ende "created" angezeigt, daher wird der Callback der create-Methode ausgeführt, als ob der Wait nicht darauf warten würde, dass die asynchrone Aufgabe "create" ausgeführt wird.

Wenn wir jedoch ein Promise hinzufügen, das aufgelöst wird, sobald der Callback von create ausgelöst wird, wie unten gezeigt, erhalten wir das erwartete Ergebnis:

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 }

Jetzt haben wir das erwartete Ergebnis.

Alle Funktionen, die auf der DB arbeiten, geben eine Zusage zurück, die, wenn sie aufgelöst wird, anzeigt, dass die Operation durchgeführt wurde, insbesondere Query. Ich gehe davon aus, dass dies auch bei model.create der Fall war, obwohl es streng genommen kein Abfrageobjekt zurückgibt. Ich frage mich auch, was das erfüllte zurückgegebene Versprechen bedeutet, da es nicht zeigt, dass das Dokument in der DB erstellt wurde. Vielleicht habe ich den ganzen Punkt übersehen, aber ich finde es etwas zweideutig

Hilfreichster Kommentar

Ich glaube, ich erinnere mich, in den 4.x-Dokumenten gelesen zu haben, dass, wenn Sie einen Rückruf an model.create übergeben, kein Versprechen zurückgegeben wird.

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

wenn Sie den Rückruf herausziehen:

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

die 5.x-Quelle für model.js bestätigt dies mit dem Aufruf von utils.promiseOrCallback

Alle 3 Kommentare

Ich glaube, ich erinnere mich, in den 4.x-Dokumenten gelesen zu haben, dass, wenn Sie einen Rückruf an model.create übergeben, kein Versprechen zurückgegeben wird.

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

wenn Sie den Rückruf herausziehen:

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

die 5.x-Quelle für model.js bestätigt dies mit dem Aufruf von utils.promiseOrCallback

Ja, @lineus hat @CodeurSauvage schließen ?

@CodeurSauvage @lineus ist korrekt, Mungo 5 gibt kein Versprechen zurück, wenn ein Rückruf angegeben ist. Ihr Skript funktioniert, wenn Sie Folgendes ersetzen:

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

Mit:

    await model.create({ a: 'test'}).then(result => console.log('created'));
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen