在任何传入的回调完成后是不是会发生 Mongoose 查询 `then` 调用?
Posted
技术标签:
【中文标题】在任何传入的回调完成后是不是会发生 Mongoose 查询 `then` 调用?【英文标题】:Will a Mongoose queries `then` call occur after any passed in callback completes?在任何传入的回调完成后是否会发生 Mongoose 查询 `then` 调用? 【发布时间】:2017-06-04 19:29:00 【问题描述】:我意识到 Mongoose 中 Promise 的标准做法是使用 exec(),但以下工作(或至少看起来是)我想了解流程。我不反对使用exec
,我只是在探索一下以学习。
在下面的 Mongoose 操作中:
let id:string;
SomeDocument.remove(, (err) => //clears collection
someDoc = new SomeDocument(data); //creates a new doc for the collection. Id is created here from what I understand.
someDoc.save( (err, result) => doSomething(); );//doSomething gets called sometime in the future.
id = someDoc._id.toString();
).then( (result) => doSomethingElse(id));//This works - but will doSomethingElse always be called after the first annonymous callback completes?
我知道doSomething()
会在未来某个时间点被调用 - 没问题。问题是,在调用then
调用中的doSomethingElse
之前,对remove 调用的第一个回调是否会完成。似乎是,id
正确填充在doSomethingElse
中,但我想确保这不仅仅是时间上的侥幸 - 即我想知道我是否可以依赖该回调在之前完成then
。我正在使用标准 ES6 承诺 (NodeJS.Global.Promise)。
另一种方法是在删除操作完成后,但在回调完成之前调用then
(似乎没有 - 但我想确认)。
如果我解释不正确,请直言。
【问题讨论】:
嗯,它是一个保存的回调,所以它会在保存操作完成后调用,实际上可能在id = someDoc._id.toString()
行执行后完成。
抱歉 - 这只是帖子中的一个错误。 doSomethingElse 是从匿名函数中调用的。我可以告诉你,当我实际执行此操作时,为 doSomething else 正确填充了 ID,因此在 doSomethingElse(id)
之前调用了行 id = someDoc._id.toString()
。所以至少它可能会在删除回调之后执行 - 问题是这是否会可靠地发生(在我的情况下确实如此,但它可能只是侥幸)。
哈哈 - 是的,你是对的。我应该只发布我的实际代码,但它有点乱。显然,当试图“简化”它时,我把它搞砸了。我修好了。谢谢!尽管如此,仍然试图找出底线 - 传递给 then
的函数是否总是在作为回调传递给我正在调用 then
的操作的函数之后执行。具体来说 - 首先执行 - 回调或 then
?
阅读代码here 看起来回调是在承诺解决后调用的。但是,由于 .then
回调被异步调用(根据 Promise/A+ 规范),.then
回调将保证在 remove
回调中的任何 同步 代码之后运行 - 所以我认为你的代码是安全的
我相信顺序是anonymous callback
, doSomethingElse
然后doSomething
【参考方案1】:
是的,正如 @JaromandaX 在 cmets 中解释的那样,回调的顺序是确定性的。
但是,它仍然是糟糕的代码,您不应该依赖这种行为。如果您正在使用 Promise,请不要将回调传递给 remove
;只将回调传递给then
!
SomeDocument.remove()
.then(() =>
const someDoc = new SomeDocument(data);
someDoc.save().then(doSomething); // doSomething will get called in the future.
return someDoc._id.toString();
//^^^^^^
)
.then(doSomethingElse); // doSomethingElse will get passed the id
doSomethingElse
将使用上一个回调的结果被调用,这是保证已经完成的。
【讨论】:
同意 - 我实际上正在重构以这样做,但由于各种原因,我不得不忍受一些混合代码。我也只是想确定一下——现在我知道回调的顺序是确定性的,这很有用!以上是关于在任何传入的回调完成后是不是会发生 Mongoose 查询 `then` 调用?的主要内容,如果未能解决你的问题,请参考以下文章