Skip to content

Commit

Permalink
docs: fix some more examples that still use callbacks re: #13616
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jul 19, 2023
1 parent f018571 commit 31b8522
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 57 deletions.
24 changes: 2 additions & 22 deletions docs/async-await.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,7 @@ This is especially helpful for avoiding callback hell when executing multiple as
Each of the three functions below retrieves a record from the database, updates it, and prints the updated record to the console.

```javascript
// Works.
function callbackUpdate() {
MyModel.findOne({ firstName: 'franklin', lastName: 'roosevelt' }, function(err, doc) {
if (err) {
handleError(err);
}

doc.middleName = 'delano';

doc.save(function(err, updatedDoc) {
if (err) {
handleError(err);
}

// Final logic is 2 callbacks deep
console.log(updatedDoc);
});
});
}

// Better.
// Using promise chaining
function thenUpdate() {
MyModel.findOne({ firstName: 'franklin', lastName: 'roosevelt' })
.then(function(doc) {
Expand All @@ -44,7 +24,7 @@ function thenUpdate() {
});
}

// Best?
// Using async/await
async function awaitUpdate() {
try {
const doc = await MyModel.findOne({
Expand Down
42 changes: 7 additions & 35 deletions docs/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,44 +104,16 @@ A full list of [Query helper functions can be found in the API docs](api/query.h
</a>
</h2>

Mongoose queries are **not** promises. They have a `.then()`
function for [co](https://www.npmjs.com/package/co) and
[async/await](http://thecodebarbarian.com/common-async-await-design-patterns-in-node.js.html)
as a convenience. However, unlike promises, calling a query's `.then()`
can execute the query multiple times.

For example, the below code will execute 3 `updateMany()` calls, one
because of the callback, and two because `.then()` is called twice.
Mongoose queries are **not** promises.
Queries are [thenables](https://masteringjs.io/tutorials/fundamentals/thenable), meaning they have a `.then()` method for [async/await](http://thecodebarbarian.com/common-async-await-design-patterns-in-node.js.html) as a convenience.
However, unlike promises, calling a query's `.then()` executes the query, so calling `then()` multiple times will throw an error.

```javascript
const q = MyModel.updateMany({}, { isDeleted: true }, function() {
console.log('Update 1');
});

q.then(() => console.log('Update 2'));
q.then(() => console.log('Update 3'));
```
const q = MyModel.updateMany({}, { isDeleted: true });

Don't mix using callbacks and promises with queries, or you may end up
with duplicate operations. That's because passing a callback to a query function
immediately executes the query, and calling [`then()`](https://masteringjs.io/tutorials/fundamentals/then)
executes the query again.

Mixing promises and callbacks can lead to duplicate entries in arrays.
For example, the below code inserts 2 entries into the `tags` array, **not** just 1.

```javascript
const BlogPost = mongoose.model('BlogPost', new Schema({
title: String,
tags: [String]
}));

// Because there's both `await` **and** a callback, this `updateOne()` executes twice
// and thus pushes the same string into `tags` twice.
const update = { $push: { tags: ['javascript'] } };
await BlogPost.updateOne({ title: 'Introduction to Promises' }, update, (err, res) => {
console.log(res);
});
await q.then(() => console.log('Update 2'));
// Throws "Query was already executed: Test.updateMany({}, { isDeleted: true })"
await q.then(() => console.log('Update 3'));
```

<h2 id="refs"><a href="#refs">References to other documents</a></h2>
Expand Down

0 comments on commit 31b8522

Please sign in to comment.