Skip to content

Instantly share code, notes, and snippets.

@bsansouci
Last active December 9, 2016 00:50
Show Gist options
  • Save bsansouci/0a03155f798ffb49a3e08c4a99e6064e to your computer and use it in GitHub Desktop.
Save bsansouci/0a03155f798ffb49a3e08c4a99e6064e to your computer and use it in GitHub Desktop.
/*
* vim: set ft=rust:
* vim: set ft=reason:
*/
/* This is pretty cool because it allows us to keep track of what the previous .thenDo returned.
Look at the one below which makes the code look a bit closer to JS.
*/
type promiseT 'a;
type responseT;
type errorT;
external fetch : string => promiseT responseT = "fetch" [@@bs.val];
external thenDo : promiseT 'a => ('a => 'b [@bs]) => promiseT 'b = "then" [@@bs.send];
external catchError : promiseT 'a => (errorT => unit [@bs]) => promiseT 'a = "catch" [@@bs.send];
external responseToText : responseT => string = "text" [@@bs.send];
let p = fetch "/greating";
let p2 = thenDo p (fun res => responseToText res);
let p3 = thenDo p2 (fun text => print_endline text);
external log : 'a => unit = "console.log" [@@bs.val];
let p4 = catchError p3 (fun err => log err);
/* This becomes
var p = fetch("/greating");
var p2 = p.then(function (res) {
return res.text();
});
var p3 = p2.then(function (text) {
console.log(text);
return /* () */0;
});
var p4 = p3.catch(function (err) {
console.log(err);
return /* () */0;
});
*/
/* You can do even shorter and closer to JS using `|>` which pipes the result of the left-hand-side to the right-hand side.
Check the JS output to make it clearer.
*/
/* Here we define _thenDo to use [@@bs.send] which wants the first argument to be the `this`, and the rest to be the args
to the function. So `external bla : 'a => 'b => unit = "bla" [@@bs.send]` can be used like `bla obj 10` and will turn into
`obj.bla(10);` in JS. We're using that API but then to support using |> we flip the order of the args in `thenDo`.
*/
external _thenDo : promiseT 'a => ('a => 'b [@bs]) => promiseT 'b = "then" [@@bs.send];
let thenDo func promise => _thenDo promise func;
external _catchError : promiseT 'a => (errorT => unit [@bs]) => promiseT 'a = "catch" [@@bs.send];
let catchError func promise => _catchError promise func;
let p = fetch "/greating"
|> thenDo (fun res => responseToText res)
|> thenDo (fun text => print_endline text)
|> catchError (fun err => log err);
/* This becomes
var p = fetch("/greating").then(function (res) {
return res.text();
}).then(function (text) {
console.log(text);
return /* () */0;
}).catch(function (err) {
console.log(err);
return /* () */0;
});
*/
/* Previous attempt. Works but isn't really type checked as much. Maybe simpler? I'd recommend using the first bindings showed */
type promiseT;
external fetch : string => promiseT = "fetch" [@@bs.val];
external thenDo : promiseT => ('a => 'b [@bs]) => promiseT = "then" [@@bs.send];
external catchError : promiseT => ('a => unit [@bs]) => promiseT = "catch" [@@bs.send];
external responseToText : 'a => string = "text" [@@bs.send];
let p = fetch "/greating";
let p2 = thenDo p (fun res => responseToText res);
let p3 = thenDo p2 (fun text => print_endline text);
/* This works because err is _any_ type and so the type checker is happy, and print_endline is turned into console.log.
I Would not recommend doing this in general. */
let p4 = catchError p3 (fun err => print_endline err);
/* This becomes
var p = fetch("/greating");
var p2 = p.then(function (res) {
return res.text();
});
var p3 = p2.then(function (text) {
console.log(text);
return /* () */0;
});
var p4 = p3.catch(function (err) {
console.log(err);
return /* () */0;
});
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment