Skip to content

Commit 14156a1

Browse files
ryangchungRyan Chung
authored and
Ryan Chung
committed
update execution page to use async/await instead of promise-based APIs
1 parent f5a367a commit 14156a1

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

src/pages/learn/execution.mdx

+15-16
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,9 @@ At the top level of every GraphQL server is an Object type that represents the p
5858
In this example, our `Query` type provides a field called `human` which accepts the argument `id`. The resolver function for this field likely accesses a database and then constructs and returns a `Human` type:
5959

6060
```js
61-
function Query_human(obj, args, context, info) {
62-
return context.db.loadHumanByID(args.id).then(
63-
userData => new Human(userData)
64-
)
61+
async function Query_human(obj, args, context, info) {
62+
const userData = await context.db.loadHumanByID(args.id);
63+
return new Human(userData);
6564
}
6665
```
6766

@@ -81,14 +80,13 @@ Note that while a query operation could technically write data to the underlying
8180
Let's take a closer look at what's happening in this resolver function:
8281

8382
```js
84-
function Query_human(obj, args, context, info) {
85-
return context.db.loadHumanByID(args.id).then(
86-
userData => new Human(userData)
87-
)
83+
async function Query_human(obj, args, context, info) {
84+
const userData = await context.db.loadHumanByID(args.id);
85+
return new Human(userData);
8886
}
8987
```
9088

91-
The `id` argument in the GraphQL query specifies the user whose data is requested, while `context` provides access to retrieve this data from a database. Since loading from a database is an asynchronous operation, this returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). In JavaScript, Promises are used to work with asynchronous values, but the same concept exists in many languages, often called _Futures_, _Tasks_, or _Deferred_. When the database returns the data, we can construct and return a new `Human` object.
89+
The `id` argument in the GraphQL query specifies the user whose data is requested, while `context` provides access to retrieve this data from a database. Since loading from a database is an asynchronous operation, we can utilize [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) / [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await). In JavaScript, `async` / `await` are used to work with asynchronous values, where `async` indicates that the function contains asynchronous operations, and `await` halts the execution of the function until the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) is resolved. The concept of Promises exists in many languages, often called _Futures_, _Tasks_, or _Deferred_. When the database returns the data, we can construct and return a new `Human` object.
9290

9391
Notice that while the resolver function needs to be aware of Promises, the GraphQL query does not. It simply expects the `human` field to return something that can be further resolved to a scalar `name` value. During execution, GraphQL will wait for Promises, Futures, and Tasks to be completed before continuing and will do so with optimal concurrency.
9492

@@ -129,16 +127,17 @@ This is an example of _scalar coercion_. The type system knows what to expect an
129127
We've already seen some of what happens when a field returns a list of things with the `appearsIn` field above. It returned a [List type](/learn/schema/#lists) containing Enum type values, and since that's what the type system expected, each item in the list was coerced to the appropriate value. What happens when the `starships` field is resolved?
130128

131129
```js
132-
function Human_starships (obj, args, context, info) {
133-
return obj.starshipIDs.map(
134-
id => context.db.loadStarshipByID(id).then(
135-
shipData => new Starship(shipData)
136-
)
137-
)
130+
async function Human_starships(obj, args, context, info) {
131+
const starships = [];
132+
for (const id of obj.starshipIDs) {
133+
const shipData = await context.db.loadStarshipByID(id);
134+
starships.push(new Starship(shipData));
135+
}
136+
return starships;
138137
}
139138
```
140139

141-
The resolver for this field is not just returning a Promise, it's returning a _list_ of Promises. The `Human` object had a list of IDs of the `Starships` they piloted, but we need to load all of those IDs to get real Starship objects.
140+
The resolver for this field is returning a _list_ of the results of Promises by asynchronously requesting each ID from the database. The `Human` object had a list of IDs of the `Starships` they piloted, but we need to load all of those IDs to get real Starship objects.
142141

143142
GraphQL will wait for all of these Promises concurrently before continuing, and when left with a list of objects, it will continue yet again to load the `name` field on each of these items concurrently.
144143

0 commit comments

Comments
 (0)