-
Notifications
You must be signed in to change notification settings - Fork 701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
async await codelab #1659
async await codelab #1659
Conversation
Feel free to ping me if I can be of use when you're building the gists for this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a great start!
- add futures codelab to sidenav - add futures codelab to /codelabs page - update 'url' global to dart.dev - move futures codelab to /codelabs/async-await (formerly incorrectly placed in /language) - sundry content corrections in futures codelab
Cool stuff! But of course, I have feedback. Some general feedback: I was surprised that there was only one embedded DartPad. I expect a lot more (inter)activity in a codelab. This feels more like a tutorial. (Maybe we can't make a codelab out of this; that's fine, a tutorial is good too.) Whether it's a tutorial or codelab, even if we don't have exercises, we should prefer letting people execute code, as opposed to just telling them what happens when the code executes. Some more specific feedback:
I didn't want to make line-by-line comments, since it sounds like the content still isn't set. (Is that right?) |
Incorporating your ideas from comments below, there may be as many as 5 total. Thanks! |
This is a really good point -- there may be some easy opportunities to replace some of the examples with an embedded DartPad. Will update you on this. |
The current draft lists only one pre-req (some experience writing asynchronous code) because if you've done that, you really can get through the codelab. Let me know if you think otherwise. |
Similar to above, I think this is a great idea. Will incorporate this. |
OK, good to know. The parts are there so that errors from test code output can reference them and give the user a clearer sense of which parts are failing. |
I actually included at least 5 embedded DartPads in the study. Considering that I didn't include all sections in the study, I would expect to have probably 8 embeds in your full version. Feel free to ping me offline as needed.
Some pre-reqs I learned from a recent UX study
For the point 2, in UX study, I invited developers with "zero Dart experience" but know other programming languages. Before jumping into this codelab, I provided a cheat sheet that introduces basic syntax used in this codelab. I can share you the cheat sheet I created. Maybe we can offer similar things to new users so that it's easier to get started (without getting lost in a tour of language doc).
The font size on mobile looks fine to me but the experience can be better. For printed version, I guess current Dartpad2 is not optimized for printing. It looks very confusing now.
+1 to this. |
If they don't need Dart experience, we should say that. |
src/codelabs/async-await/index.md
Outdated
|
||
<iframe frameborder="no" height="525" src="https://dartpad2-ux.firebaseapp.com/experimental/embed-new?id=f751b692502c4ee43d932f745860b056" width="100%"></iframe> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use production links for Dartpad2 instead of the UX experimental site.
https://dartpad.dartlang.org/experimental/embed-new.html?id=f751b692502c4ee43d932f745860b056
We have a cheatsheet on the site, but I haven't linked to it, because I didn't feel like it was ready yet (details at #1625 (comment)) . Maybe we can merge it and your cheatsheet? Here's the semi-published cheatsheet: https://dart.dev/guides/language/cheatsheet (Rereading your comment, I see that my cheatsheet should probably be a superset of yours, @galeyang.) |
Sounds good, I'll use the pre-reqs that Gale drew from the studies (including needing at least a little bit of dart experience). I'll also take a closer look at the various cheatsheet options we've proposed. |
src/codelabs/async-await/index.md
Outdated
@@ -176,23 +177,27 @@ when using `async` and `await`: | |||
* __The `await` keyword works only in `async` functions.__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverse the order of these two lines? In the following part, you first talk about async and then await.
If the function has a declared return type, then update the type to be `Future<T>`, | ||
where `T` is the type of the value that the function returns. | ||
If the function doesn't explicitly return a value, then the return type is `Future<void>`: | ||
|
||
{% prettify dart %} | ||
[!Future<void>!] main() async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little confusing to me that you added Future before the main() but didn't include this in the later side-by-side example.
The content says "If needed, update the function’s type signature". This makes me wonder "so why did you add a function’s type signature here but didn't add a function’s type signature in "Example: asynchronous functions".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm removing the If needed, update the function's type signature
sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your point about you added Future before the main() but didn't include this in the later side-by-side example.
, which is why I think main()
might not be the best choice for this example. @kathyw thoughts? It seems sort of odd to show examples with Future<void> main()
everywhere, but it also seems odd to do it in some places but not others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about the rationale of changing from converts createOrderMessage ()
to concerts main()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to remember why we changed from createOrderMessage()
to main()
. I agree that it might be better to show something that isn't main()
, so we don't have to dance around the return type declaration being OK to leave off. (Or we can do the dance later.)
I think the text was inconsistent about Future<void>
vs. Future<TypeOfWhatYouReturn>
, so we picked Future<void>
. Also, maybe we wanted to handle the no-return case? But we could do that separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe we wanted to handle the no-return case? But we could do that separately.
It seems that both examples in the What is a future? section has handled the no-return case using Future<void>
.
src/codelabs/async-await/index.md
Outdated
description: Learn about and practice writing asynchronous code in DartPad! | ||
--- | ||
This codelab teaches you how to write asynchronous code using | ||
futures and the `async` and `await` keywords. This codelab includes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting two sentences in a row with "This codelab" isn't ideal. My original suggestion was this:
This codelab teaches you how to write asynchronous....
Using the embedded DartPad editors, you can test your...
src/codelabs/async-await/index.md
Outdated
|
||
Here's an example that converts `main()` from a synchronous to asynchronous function. | ||
|
||
First, add the `async` keyword before the function body. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this change. The style guide favors using a colon if the intro immediately precedes the sample (https://developers.google.com/style/code-samples#intros).
src/codelabs/async-await/index.md
Outdated
Remember, you can only use the `await` keyword within an `async` function. | ||
The following examples provide a comparison of synchronous and asynchronous functions. | ||
If your window is wide enough, you'll see the two examples side-by-side. | ||
Now that you have an async function, you can use the `await` keyword to wait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async function -> async
function (global)
src/codelabs/async-await/index.md
Outdated
{{ site.alert.end }} | ||
|
||
## Execution flow with async and await | ||
|
||
As of Dart 2, functions marked as `async` run synchronously until the first | ||
`await` keyword. This means that within an `async` function body, all | ||
Async functions run synchronously until the first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Async functions run -> An async
function runs
Maybe say just "A bit later you'll learn how to handle the error." |
src/codelabs/async-await/index.md
Outdated
@@ -306,35 +324,40 @@ code snippets. Your task is to complete the exercise by writing code to make the | |||
tests pass. | |||
You don't need to implement `main()`. | |||
|
|||
To simulate asynchronous operations, your code will call the following functions, which are | |||
To simulate asynchronous operations, call the following functions which are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which -> , which
src/codelabs/async-await/index.md
Outdated
* Example return value from `reportUserRole()`: `"User role: tester"` | ||
* Note: you must use the actual value returned by `getRole()`; copying and pasting the example return value won't make the test pass. | ||
* Get the user role by calling the provided function `getRole()` | ||
Add code to the `reportUserRole` function so that it does the following: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reportUserRole -> reportUserRole()
src/codelabs/async-await/index.md
Outdated
Add code to the `reportUserRole` function so that it does the following: | ||
<!-- Some bulleted items are intentionally lacking punctuation to avoid | ||
confusing the users about characters in string values --> | ||
* `reportUserRole()` Returns a future that completes with the following |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete reportUserRole()
src/codelabs/async-await/index.md
Outdated
|
||
#### Part 2: `reportLogins()` | ||
Implement an `async` function `reportLogins()`: | ||
Implement an async function `reportLogins()`: | ||
* `reportLogins()` returns the string `"Total number of logins: <# of logins>"`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar changes to above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more comments... I hope these don't get lost in GH!
@@ -277,21 +277,21 @@ The asynchronous example is different in three ways: | |||
**Key terms:** | |||
* **async**: You can use the `async` keyword before a function's body to mark it as | |||
asynchronous. | |||
* **async function**: An async function is a function labeled with the `async` | |||
* **async function**: An `async` function is a function labeled with the `async` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async function -> async
function
Uh oh, the build failed (on both stable & dev). Something about the code excerpts, but I didn't think you changed anything in the code. Can you figure this out, @legalcodes? (Or I can look at it tomorrow.) Issue reported: #1818 |
Thanks for alerting me to this, I'll take look, will see what turns up. |
{{ site.alert.end }} | ||
|
||
## What's next? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a brief intro paragraph here.
src/codelabs/async-await/index.md
Outdated
|
||
{{ site.alert.info }} | ||
You might have noticed that the functions in the exercises don't have return types. That's because Dart can infer the return type for you. Omitting return types is fine when you're prototyping, but when you write production code, we recommend that you specify the return type. | ||
Dart can [infer the return type](https://dart.dev/guides/language/sound-dart#type-inference) for you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this final sentence, and move the link up to the second sentence of this note.
src/codelabs/async-await/index.md
Outdated
## What's next? | ||
|
||
* [Asynchronous programming: futures & async-await](/tutorials/language/futures) tutorial | ||
* [Dart's type system](/guides/language/sound-dart) (Includes more examples of type signatures with futures). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Includes more -> has
). -> )
src/codelabs/async-await/index.md
Outdated
|
||
## What's next? | ||
|
||
* [Asynchronous programming: futures & async-await](/tutorials/language/futures) tutorial |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good to have sub-items. Maybe something like this:
- Play with DartPad
- Try another codelab or a tutorial:
- [Dart codelabs]
- [Asynchronous programming...]
- Read about [Dart's type system].
src/codelabs/async-await/index.md
Outdated
* [Asynchronous programming: futures & async-await](/tutorials/language/futures) tutorial | ||
* [Dart's type system](/guides/language/sound-dart) (Includes more examples of type signatures with futures). | ||
* [Preferring signatures in function type annotations](/guides/language/effective-dart/design#prefer-signatures-in-function-type-annotations) | ||
* [Effective Dart](/guides/language/effective-dart) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these two Effective Dart links really something they might want to go to next? If so, explain why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this tutorial https://dart.dev/tutorials/language/futures cover more content than this codelab? If it's mostly repetitive, maybe it's "other resources' rather than "next step".
--
In the previous UX study, users said they want to learn more about how Dart handles threads, controlling flow/loop, scheduling, and more complex asynchronous tasks other than grabbing values. It seems like Dart uses streams
, Isolates
, event loops
for these Android related concepts. Hence, we can consider adding these two docs as next step.
- Asynchronous programming: streams tutorial: show you how to work with sequence of asynchronous events.
- Dart asynchronous programming: Isolates and event loops (link to an external doc on Dart's Medium)
src/codelabs/async-await/index.md
Outdated
{:.table .table-striped} | ||
|
||
Use `async` and `await` to do the following: | ||
* Implement an asynchronous `changeUsername()` function that calls the provided |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flow seems slightly off. How about this:
Use async and await to implement an asynchronous changeUsername() function that does the following:
- Calls the provided asynchronous function getNewUsername() and returns the result.
- Example...
- Catches any error that occurs and returns the string value of the error.
- You can use...
### Exercise: Putting it all together | ||
|
||
It's time to practice what you've learned in one final exercise. | ||
To simulate asynchronous operations, this exercise provides the asynchronous |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this sentence and the next one, or combine them somehow with the next paragraph. (As is, it's too repetitive.)
src/codelabs/async-await/index.md
Outdated
* `greetUser()` creates a greeting for the user by calling `addHello()`, | ||
passing it the username, and returning the result. | ||
* For example, if the username is "Jenny", `greetUser()` should create and | ||
return the greeting "Hello Jenny" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jenny" -> Jenny".
OR
the greeting... -> the following: "Hello Jenny"
src/codelabs/async-await/index.md
Outdated
#### Part 3: `sayGoodbye()` | ||
<!-- pull out descriptions of --> | ||
* Write a function `sayGoodbye()` that does the following: | ||
* `sayGoodbye()` takes no arguments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent this and the following 2 items.
Delete the function name and capitalize the verb:
- ...following:
- Takes no arguments.
- Catches any errors.
- Calls...
- If... succeeds,
sayGoodbye()
returns the string...
* `sayGoodbye()` calls the provided asynchronous function `logoutUser()`. | ||
<!-- italicize <result> --> | ||
* If `logoutUser()` succeeds, `sayGoodbye()` returns the string "\<result\> | ||
Thanks, see you next time" where \<result\> is the String value returned by calling `logoutUser()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returned by calling -> produced (eventually) by logoutUser()
.
(or something else that acknowledges that logoutUser doesn't return a string value)
src/codelabs/async-await/index.md
Outdated
@@ -387,7 +387,7 @@ the same way you would in synchronous code. | |||
|
|||
### Example: async and await with try-catch | |||
Run the following example to see how to handle an error from an | |||
asynchronous function. Can you guess what the output will be before running it? | |||
asynchronous function. What do you think the output will be before running it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete "before running it"
src/codelabs/async-await/index.md
Outdated
asynchronous expression. The `await` keyword only works within an `async` function. | ||
{{ site.alert.end }} | ||
|
||
## Execution flow with async and await |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
##
-> ###
(I noticed in the side nav that the exercise applies to "Working with futures", not "Execution flow". I think this change fixes that problem.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
Staged:
https://jt-ww-1.firebaseapp.com/codelabs/async-await
Remaining tasks: (last updated 7/19)