Skip to content

Commit 910f9fc

Browse files
authored
Add documentation for async/await. (#590)
* Add documentation for async/await. * Build using newer compiler. * format * Use newer compiler for tests. * Make tests compile. * Review comments. * regexp escape * newline * string split * format * regexp * tab * Get around vercel's incompetent cache. * A few words in the async+promise sections.
1 parent 317fdf0 commit 910f9fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+653
-668
lines changed

compilers/package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compilers/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"rescript-820": "npm:bs-platform@8.2.0",
99
"rescript-902": "npm:bs-platform@9.0.2",
1010
"rescript-912": "npm:rescript@9.1.2",
11-
"rescript-1000": "npm:rescript@10.0.0"
11+
"rescript-1000": "npm:rescript@10.0.0",
12+
"rescript-1010": "npm:rescript@10.1.0-rc.4"
1213
}
1314
}

package-lock.json

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
},
3737
"scripts": {
3838
"dev": "next",
39-
"build": "rescript && npm run update-index && next build",
39+
"build": "rescript clean -with-deps && rescript && npm run update-index && next build",
4040
"test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs",
4141
"reanalyze": "reanalyze -all-cmt .",
4242
"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"
@@ -47,7 +47,7 @@
4747
"esbuild-loader": "^2.13.1",
4848
"postcss-cli": "^8.3.0",
4949
"reanalyze": "^2.16.0",
50-
"rescript": "9.1.2",
50+
"rescript": "^10.1.0-rc.4",
5151
"tailwindcss": "^2.1.4"
5252
}
5353
}

pages/docs/manual/latest/function.mdx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,78 @@ If you write down the uncurried function's type, you'll add a dot there as well.
415415

416416
**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.
417417

418+
## Async/Await (from v10.1)
419+
420+
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.
421+
The output looks like idiomatic JS:
422+
423+
<CodeTab labels={["ReScript", "JS Output"]}>
424+
425+
```res example
426+
let getUserName = async (userId) => userId
427+
428+
let greetUser = async (userId) => {
429+
let name = await getUserName(userId)
430+
"Hello " ++ name ++ "!"
431+
}
432+
```
433+
```js
434+
async function greetUser(userId) {
435+
var name = await getUserName(userId);
436+
return "Hello " + name + "!";
437+
}
438+
```
439+
</CodeTab>
440+
441+
The return type of `getUser` is inferred to be `promise<string>`.
442+
Similarly, `await getUserName(userId)` returns a `string` when the function returns `promise<string>`.
443+
Using `await` outside of an `async` function (including in a non-async callback to an async function) is an error.
444+
445+
### Ergonomic error handling
446+
447+
Error handling is done by simply using `try`/`catch`, or a switch with an `exception` case, just as in functions that are not async.
448+
Both JS exceptions and exceptions defined in ReScript can be caught. The compiler takes care of packaging JS exceptions into the builtin `JsError` exception:
449+
450+
<CodeTab labels={["ReScript", "JS Output"]}>
451+
452+
```res example
453+
exception SomeReScriptException
454+
455+
let somethingThatMightThrow = async () => raise(SomeReScriptException)
456+
457+
let someAsyncFn = async () => {
458+
switch await somethingThatMightThrow() {
459+
| data => Some(data)
460+
| exception JsError(_) => None
461+
| exception SomeReScriptException => None
462+
}
463+
}
464+
```
465+
```js
466+
var SomeReScriptException = /* @__PURE__ */Caml_exceptions.create("Example.SomeReScriptException");
467+
468+
async function someAsyncFn(param) {
469+
var data;
470+
try {
471+
data = await somethingThatMightThrow(undefined);
472+
}
473+
catch (raw_exn){
474+
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
475+
if (exn.RE_EXN_ID === "JsError") {
476+
return ;
477+
}
478+
if (exn.RE_EXN_ID === SomeReScriptException) {
479+
return ;
480+
}
481+
throw exn;
482+
}
483+
return data;
484+
}
485+
```
486+
</CodeTab>
487+
488+
489+
418490
## The ignore() Function
419491

420492
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 `()`:

pages/docs/manual/latest/promise.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ canonical: "/docs/manual/latest/promise"
66

77
# Async & Promise
88

9-
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.
10-
11-
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.
9+
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.
1210

1311
## Promise (new)
1412

scripts/generate_feed.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ console.log(content);
88

99
export {
1010
content ,
11-
1211
}
1312
/* content Not a pure module */

scripts/test-examples.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let tempFileNameRegex = /_tempFile\.res/g
1414
// see the package.json on how to define another rescript version
1515
let compilersDir = path.join(__dirname, "..", "compilers")
1616

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

1919
const prepareCompilers = () => {
2020
if (fs.existsSync(bsc)) {

src/Blog.mjs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function Blog$CategorySelector(Props) {
4444
}, Belt_Array.map(tabs, (function (tab) {
4545
var onClick = function (evt) {
4646
evt.preventDefault();
47-
return Curry._1(onSelected, tab);
47+
Curry._1(onSelected, tab);
4848
};
4949
var isActive = selected === tab;
5050
var text = tab ? "Archived" : "All";
@@ -245,9 +245,9 @@ function $$default(props) {
245245
}, React.createElement(Blog$CategorySelector, {
246246
selected: currentSelection,
247247
onSelected: (function (selection) {
248-
return Curry._1(setSelection, (function (param) {
249-
return selection;
250-
}));
248+
Curry._1(setSelection, (function (param) {
249+
return selection;
250+
}));
251251
})
252252
}))), result);
253253
}
@@ -301,6 +301,5 @@ export {
301301
$$default ,
302302
$$default as default,
303303
getStaticProps ,
304-
305304
}
306305
/* middleDotSpacer Not a pure module */

src/BlogArticle.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,5 @@ export {
213213
$$default as default,
214214
getStaticProps ,
215215
getStaticPaths ,
216-
217216
}
218217
/* middleDotSpacer Not a pure module */

src/Design.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,5 @@ var $$default = Design$default;
3232
export {
3333
$$default ,
3434
$$default as default,
35-
3635
}
3736
/* react Not a pure module */

src/DocsOverview.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function DocsOverview$default(Props) {
8585
var version = evt.target.value;
8686
var url = Url.parse(router.route);
8787
var targetUrl = "/" + (url.base.join("/") + ("/" + (version + ("/" + url.pagepath.join("/")))));
88-
return Next.Router.push(router, targetUrl);
88+
Next.Router.push(router, targetUrl);
8989
};
9090
versionSelect = React.createElement("div", {
9191
className: "text-fire"
@@ -120,6 +120,5 @@ var $$default = DocsOverview$default;
120120
export {
121121
$$default ,
122122
$$default as default,
123-
124123
}
125124
/* Next Not a pure module */

0 commit comments

Comments
 (0)