0
const deleteTaskCount = async(id) => {
const task = Task.findByIdAndDelete(id);
const count = await Task.countDocument({completed:false})
return count;

}

deleteTaskCount("1234").then((count)=>{
console.log(count);
})

I understood that with await in const task = Task.findByIdAndDelete(id); it deletes the user with the id.But without the await keyword(like in the above function) the function still happens, that is it deletes the user but in a non-blocking way after some time.When i ran the above code the count is showing properly but the const task = Task.findByIdAndDelete(id); is not deleting the user.

vawoh
  • 1
  • 1
  • `Task.findByIdAndDelete()` take time to delete `id`, But you read `Task.countDocument` immediately, when `id` didn't deleted, and `await` keyword don't block your code, – Nur May 02 '21 at 19:30
  • Don't afraid to use `await` keyword, It don't block your code, Even Its impossible to block any I/O in JavaScript, – Nur May 02 '21 at 19:35
  • "*the `const task = Task.findByIdAndDelete(id);` is not deleting the user.*" - how do you determine that it hasn't deleted the user? – Bergi May 03 '21 at 00:10
  • Kept the code running and was constantly checking in Mongo compass..It wasn't getting deleted.If the operation is completed some time later,It has to be deleted right? – vawoh May 03 '21 at 04:13

2 Answers2

0

You should use await for the Task.findByIdAndDelete(id) as well. When you use await, NodeJS will go do some other things until that resolves, and it will only then continue to execute the function (it will not block your code at all).

const deleteTaskCount = async(id) => {
  const task = await Task.findByIdAndDelete(id);
  const count = await Task.countDocument({completed:false})
  return count;
}

deleteTaskCount("1234").then((count)=>{
  console.log(count);
})
NeNaD
  • 18,172
  • 8
  • 47
  • 89
0

I don't know much about the mongoose API but I suspect mongoose.query behaves similar to mongo cursors and many other asynchronous database drivers/ORMs. Queries often don't execute unless awaited or chained upon.

In any case, without awaiting Task.findByIdAndDelete, there's no guarantee in concurrency between the two queries. If you want the result of countDocument to reflect the changes in findByIdAndDelete, you must wait on the client-side for that query to complete and then run countDocument.

You would achieve this by adding the await keyword before Task.findByIdAndDelete.

I'd presonally recommend using the promises/thenables as opposed to await/async.

Task.findByIdAndDelete("1234")
  .then(task => Task.countDocument({completed:false}))
  .then(count => console.log(count));

Imho, it's cleaner, less error prone, more functional, less confusing. YMMV

CervEd
  • 3,306
  • 28
  • 25
  • Let's say Task.findByIdAndDelete() and countDocument() are completed unrelated.If i don't use await or don't provide a .then() for Task.findByIdAndDelete(), will it still go ahead and delete the user after some time? or do we need to have await or .then() or callback for queries to execute like you said? – vawoh May 03 '21 at 04:23
  • If they are unrelated, you can use something like `Promise.all` / `allSettled` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled which turns multiple promises into a single promise, then `await` or `then` that. Note the difference between `thenables` / `Promises`, there's more info in the link in my post. You probably have to convert thenables to promises (maybe using exec?) – CervEd May 03 '21 at 08:47
  • Use `all` when a single failure should fail all promises. Use `allSettled` when you don't – CervEd May 03 '21 at 08:50
  • They are unrelated,that is why i kept them as seperate promises..wrote this code to try to understand async/await. If i leave the code as i mentioned it in question `Task.findByIdAndDelete(id)`..since i am not awaiting or not using the result from the promise anywhere, the line just doesn't run and delete the task..Is that it? If there are multiple asynchronous functions in asyc function..and one of them doesnt have await...Will the line without await get executed? – vawoh May 04 '21 at 01:57
  • @vawoh, strictly speaking, all lines are "executed". The question is what that execution does. In your case, it looks like `findByIdAndDelete` creates a `query` object https://mongoosejs.com/docs/api.html#Query. From glancing through the documentation, and what I'd expect from working with other similar APIs is that the query doesn't get sent to the database until you tell it to. I'd guess in this case, either by calling `exec()` or `then` or using `await`. Note that *queries* appear to be promise-like objects. Ie: support different Promise methods but not necessarily all – CervEd May 04 '21 at 09:50
  • @vawoh, the best way to see which queries are actually sent to the database is to monitor the mongodb query log. This may be helpful https://stackoverflow.com/questions/15204341/mongodb-logging-all-queries – CervEd May 04 '21 at 09:56