Skip to content

Add documentation for async/await. #590

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

Merged
merged 14 commits into from
Nov 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions compilers/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion compilers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"rescript-820": "npm:bs-platform@8.2.0",
"rescript-902": "npm:bs-platform@9.0.2",
"rescript-912": "npm:rescript@9.1.2",
"rescript-1000": "npm:rescript@10.0.0"
"rescript-1000": "npm:rescript@10.0.0",
"rescript-1010": "npm:rescript@10.1.0-rc.4"
}
}
12 changes: 7 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"scripts": {
"dev": "next",
"build": "rescript && npm run update-index && next build",
"build": "rescript clean -with-deps && rescript && npm run update-index && next build",
"test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs",
"reanalyze": "reanalyze -all-cmt .",
"update-index": "node scripts/extract-indices.mjs && node scripts/extract-tocs.mjs && node scripts/extract-syntax.mjs && node scripts/generate_feed.mjs > public/blog/feed.xml"
Expand All @@ -47,7 +47,7 @@
"esbuild-loader": "^2.13.1",
"postcss-cli": "^8.3.0",
"reanalyze": "^2.16.0",
"rescript": "9.1.2",
"rescript": "^10.1.0-rc.4",
"tailwindcss": "^2.1.4"
}
}
72 changes: 72 additions & 0 deletions pages/docs/manual/latest/function.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,78 @@ If you write down the uncurried function's type, you'll add a dot there as well.

**This feature seems trivial**, but is actually one of our most important features, as a primarily functional language. We encourage you to use it if you'd like to remove any mention of `Curry` runtime in the JS output.

## Async/Await (from v10.1)

Just as in JS, an async function can be declared by adding `async` before the definition, and `await` can be used in the body of such functions.
The output looks like idiomatic JS:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
let getUserName = async (userId) => userId

let greetUser = async (userId) => {
let name = await getUserName(userId)
"Hello " ++ name ++ "!"
}
```
```js
async function greetUser(userId) {
var name = await getUserName(userId);
return "Hello " + name + "!";
}
```
</CodeTab>

The return type of `getUser` is inferred to be `promise<string>`.
Similarly, `await getUserName(userId)` returns a `string` when the function returns `promise<string>`.
Using `await` outside of an `async` function (including in a non-async callback to an async function) is an error.

### Ergonomic error handling

Error handling is done by simply using `try`/`catch`, or a switch with an `exception` case, just as in functions that are not async.
Both JS exceptions and exceptions defined in ReScript can be caught. The compiler takes care of packaging JS exceptions into the builtin `JsError` exception:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
exception SomeReScriptException

let somethingThatMightThrow = async () => raise(SomeReScriptException)

let someAsyncFn = async () => {
switch await somethingThatMightThrow() {
| data => Some(data)
| exception JsError(_) => None
| exception SomeReScriptException => None
}
}
```
```js
var SomeReScriptException = /* @__PURE__ */Caml_exceptions.create("Example.SomeReScriptException");

async function someAsyncFn(param) {
var data;
try {
data = await somethingThatMightThrow(undefined);
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
if (exn.RE_EXN_ID === "JsError") {
return ;
}
if (exn.RE_EXN_ID === SomeReScriptException) {
return ;
}
throw exn;
}
return data;
}
```
</CodeTab>



## The ignore() Function

Occasionally you may want to ignore the return value of a function. ReScript provides an `ignore()` function that discards the value of its argument and returns `()`:
Expand Down
4 changes: 1 addition & 3 deletions pages/docs/manual/latest/promise.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ canonical: "/docs/manual/latest/promise"

# Async & Promise

ReScript's primary mechanism for async programming is the same as JavaScript's (callbacks and promises), since we compile cleanly to JavaScript and would like to avoid dragging in a heavy custom runtime.

There is currently no support for `async` and `await` keywords in ReScript; though our new Promise API bindings revamp + [pipe](pipe) will make your async code already look better than otherwise.
Support for `async` and `await` is added in compiler version 10.1. The majority of existing code is based on promises. The new Promise API bindings make async code look better than with old promises.

## Promise (new)

Expand Down
1 change: 0 additions & 1 deletion scripts/generate_feed.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ console.log(content);

export {
content ,

}
/* content Not a pure module */
2 changes: 1 addition & 1 deletion scripts/test-examples.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let tempFileNameRegex = /_tempFile\.res/g
// see the package.json on how to define another rescript version
let compilersDir = path.join(__dirname, "..", "compilers")

let bsc = path.join(compilersDir, 'node_modules', 'rescript-1000', process.platform, 'bsc.exe')
let bsc = path.join(compilersDir, 'node_modules', 'rescript-1010', process.platform, 'bsc.exe')

const prepareCompilers = () => {
if (fs.existsSync(bsc)) {
Expand Down
9 changes: 4 additions & 5 deletions src/Blog.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function Blog$CategorySelector(Props) {
}, Belt_Array.map(tabs, (function (tab) {
var onClick = function (evt) {
evt.preventDefault();
return Curry._1(onSelected, tab);
Curry._1(onSelected, tab);
};
var isActive = selected === tab;
var text = tab ? "Archived" : "All";
Expand Down Expand Up @@ -245,9 +245,9 @@ function $$default(props) {
}, React.createElement(Blog$CategorySelector, {
selected: currentSelection,
onSelected: (function (selection) {
return Curry._1(setSelection, (function (param) {
return selection;
}));
Curry._1(setSelection, (function (param) {
return selection;
}));
})
}))), result);
}
Expand Down Expand Up @@ -301,6 +301,5 @@ export {
$$default ,
$$default as default,
getStaticProps ,

}
/* middleDotSpacer Not a pure module */
1 change: 0 additions & 1 deletion src/BlogArticle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,5 @@ export {
$$default as default,
getStaticProps ,
getStaticPaths ,

}
/* middleDotSpacer Not a pure module */
1 change: 0 additions & 1 deletion src/Design.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ var $$default = Design$default;
export {
$$default ,
$$default as default,

}
/* react Not a pure module */
3 changes: 1 addition & 2 deletions src/DocsOverview.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function DocsOverview$default(Props) {
var version = evt.target.value;
var url = Url.parse(router.route);
var targetUrl = "/" + (url.base.join("/") + ("/" + (version + ("/" + url.pagepath.join("/")))));
return Next.Router.push(router, targetUrl);
Next.Router.push(router, targetUrl);
};
versionSelect = React.createElement("div", {
className: "text-fire"
Expand Down Expand Up @@ -120,6 +120,5 @@ var $$default = DocsOverview$default;
export {
$$default ,
$$default as default,

}
/* Next Not a pure module */
Loading