简体   繁体   English

Mongoose 承诺文档说查询不是承诺?

[英]Mongoose promises documentation says queries are not promises?

From the docs ( Mongoose v5.4.1 , latest version):来自文档( Mongoose v5.4.1 ,最新版本):

Mongoose async operations, like .save() and queries, return thenables. Mongoose 异步操作,如 .save() 和查询,返回 thenables。 This means that you can do things like MyModel.findOne({}).then()这意味着您可以执行 MyModel.findOne({}).then() 之类的操作

second parapraph from the docs states:文档中的第二段说明:

Mongoose queries are not promises. Mongoose 查询不是承诺。 They have a .then() function for co and async/await as a convenience.为了方便起见,它们有一个用于 co 和 async/await 的 .then() 函数。

What Javascript MDN webpage states: Javascript MDN网页说明了什么:

The then() method returns a Promise. then() 方法返回一个 Promise。

Does this mean that mongoose has another kind of implementation for async functions where they reserved the then keyword for the result of the async action?这是否意味着 mongoose 有另一种异步函数实现,它们为异步操作的结果保留了 then 关键字?

In other words, they act like promises but are not JS promises?换句话说,它们的行为就像承诺,但不是 JS 承诺?

From the documentation :文档

Mongoose queries are not promises. Mongoose 查询不是承诺。 They have a .then() function for co and async/await as a convenience.为了方便起见.then()它们有一个用于 co 和 async/await 的.then()函数。 However, unlike promises, calling a query's .then() can execute the query multiple times.但是,与 promise 不同的是,调用查询的.then()可以多次执行查询。

So unlike an actual promise, if you call then() multiple times on the query, you actually execute the query (or update) multiple times.因此,与实际的承诺不同,如果您对查询多次调用then() ,您实际上会多次执行查询(或更新)。

If you want an actual promise, call exec() on the query.如果您想要一个实际的承诺,请在查询上调用exec()

let promise = Test.findOne({}).exec();

All promises are thenables , but not all thenables are promises .所有的承诺都是thenables ,但并非所有的thenables都是承诺 To make things more complicated, not all promises are Promise s (instances created by JavaScript's built-in Promise constructor).更复杂的是,并非所有的promise都是Promise (由 JavaScript 的内置Promise构造函数创建的实例)。

JavaScript promises are an implementation of the Promises/A+ specification , which defines the terms like this: JavaScript promises 是Promises/A+ 规范的实现,它定义了这样的术语:

1.1 “promise” is an object or function with a then method whose behavior conforms to this specification. 1.1 “promise”是具有then方法的对象或函数,其行为符合本规范。

1.2 “thenable” is an object or function that defines a then method. 1.2 “thenable”是定义then方法的对象或函数。

So Mongoose's queries are not promises, not even by that definition, since their then method is not compatible with the Promises/A+ spec.所以 Mongoose 的查询不是承诺,甚至不是那个定义,因为他们的then方法与 Promises/A+ 规范兼容。 See JohnnyHK's answer for why they aren't compatible with the Promises/A+ spec (they run the query).请参阅JohnnyHK 的回答,了解为什么它们与 Promises/A+ 规范不兼容(它们运行查询)。

In other words, they act like promises but are not JS promises?换句话说,它们的行为就像承诺,但不是 JS 承诺?

They only act a bit like promises.他们只是有点像承诺。 They are not promises.它们不是承诺。 Their then is not implemented per the spec, it has side effects (running the query).他们的then不是按照规范实现的,它有副作用(运行查询)。 If you want a true promise, see JohnnyHK's answer (eg, use exec ).如果您想要一个真正的承诺,请参阅JohnnyHK 的回答(例如,使用exec )。


In general, if you have a thenable that's at least somewhat promise-like, you can get a proper promise for it by using Promise.resolve :一般来说,如果你有一个至少有点像 promise 的thenable ,你可以通过使用Promise.resolve来获得一个正确的 promise:

Promise.resolve(theThenable)
.then(/*...*/)
.catch(/*...*/)
.finally(/*...*/);

Promise.resolve will provide a true Promise instance that is resolved to the Mongoose thenable/promise: It will wait for that thenable/promise to settle and then settle the same way. Promise.resolve将提供一个真正的Promise实例,该实例被解析为Mongoose thenable/promise:它将等待 thenable/promise 解决,然后以相同的方式解决。 That would work on a Mongoose query (provided you only do it once; exec is the better way with Mongoose queries).这将适用于 Mongoose 查询(前提是您只执行一次; exec是使用 Mongoose 查询的更好方法)。

他们是“诺如”,这意味着你可以await他们,叫.then().catch()在他们身上,但是他们都没有instanceof Promise

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM