在任何传入的回调完成后是不是会发生 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` 调用?的主要内容,如果未能解决你的问题,请参考以下文章

异步回调CompletableFuture

解决回调函数

CSS3 动画完成时是不是有回调?

在 Flutter 中完成“构建”功能时是不是有任何回调告诉我?

OpenSSL 是不是有任何“读取”数据的事件回调函数?

选项菜单创建完成时回调