Mongoose: 虽然没有保存文档,但 Model.create Promise 已解决

创建于 2018-02-01  ·  3评论  ·  资料来源: Automattic/mongoose

大家好,

我使用的是猫鼬版本 5.0.3 和节点版本 9.4.0。 根据 mongoose 文档,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 方法的回调被执行,就好像 await 没有等待异步任务“create”完成一样。

但是通过添加一个 promise,一旦 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 }

现在我们有了预期的结果。

所有对 DB 进行操作的函数都会返回一个承诺,如果解决了就表明操作已经完成,特别是 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> }

model.js 的 5.x 源代码支持调用 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> }

model.js 的 5.x 源代码支持调用 utils.promiseOrCallback

是的, @lineus是正确的,我可以关闭这个问题@CodeurSauvage吗?

@CodeurSauvage @lineus是正确的,猫鼬5如果指定了回调返回的承诺。 如果您替换,您的脚本将起作用:

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

和:

    await model.create({ a: 'test'}).then(result => console.log('created'));
此页面是否有帮助?
0 / 5 - 0 等级