I usually stay away from directly interacting with Promise
s or async
/await
syntax and use Futures or Tasks instead. In JS/TS land I use fluture
or fp-ts
for this. There are bindings for libraries that already exist and some older ReScript implementations, but I wanted something lightweight that had an API that was focused on usage in ReScript v11 with the Core library.
Here’s an example.
let _ =
Future.fetch("http://httpstat.us/200")
->Future.flatMap(res => {
switch res->Webapi.Fetch.Response.ok {
| true => Ok(res)
| false =>
Error(`${res->Fetch.Response.status->Int.toString}: ${res->Fetch.Response.statusText}`)
}
})
->Future.map(res => res->Fetch.Response.statusText)
->Future.fold(Console.error, Console.log)
A future will never throw an error, even if the promise call does. It gets caught and returned as an Error
.
Here’s an example of cancelling a future in React.
@react.component
let make = () => {
let request = Future.fetch("http://httpstat.us/200?sleep=1000")
<div>
<button
onClick={_ => {
request->Future.reset // reset the future to make sure the Abort Controller is new
Console.log("clicked!")
let _ = request->Future.fold(Console.error, Console.log)
}}>
{"Start"->React.string}
</button>
<button
onClick={_ => {
let _ = request->Future.cancel // Aborts the fetch request and stops any processing of the response
}}>
{"Cancel"->React.string}
</button>
</div>
}