Skip to content
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
26 changes: 13 additions & 13 deletions src/js/async.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub async fn suspend[T, E : Error](
) -> T!E = "%async.suspend"

///|
pub fn async_run(f : async () -> Unit) -> Unit = "%async.run"
pub fn async_run(f : () -> Unit!Async) -> Unit = "%async.run"

///|
/// # Safety
Expand All @@ -26,7 +26,7 @@ extern "js" fn Promise::wait_ffi(

///|
pub async fn Promise::wait(self : Promise) -> Value! {
suspend!!(fn(k, ke) { Promise::wait_ffi(self, k, fn(e) { ke(Error_(e)) }) })
suspend!(fn(k, ke) { Promise::wait_ffi(self, k, fn(e) { ke(Error_(e)) }) })
}

///|
Expand All @@ -38,19 +38,19 @@ pub async fn Promise::wait(self : Promise) -> Value! {
/// This makes sure that when `op` errs out, the error is caught by the MoonBit runtime.
///
/// If you don't care about the result of the operation, you can use `spawn_detach` instead.
pub fn Promise::unsafe_new[T](op : async () -> T!) -> Promise {
Promise::new_ffi(fn() { Value::cast_from(op!!()) })
pub fn Promise::unsafe_new[T](op : () -> T!Error + Async) -> Promise {
Promise::new_ffi(fn() { Value::cast_from(op!()) })
}

///|
extern "js" fn Promise::new_ffi(op : async () -> Value!) -> Promise =
extern "js" fn Promise::new_ffi(op : () -> Value!Error + Async) -> Promise =
#| (op) => new Promise((k, ke) => op(k, ke))

///|
pub fn spawn_detach[T, E : Error](op : async () -> T!E) -> Unit {
pub fn spawn_detach[T, E : Error](op : () -> T!E + Async) -> Unit {
async_run(fn() {
try {
op!!() |> ignore
op!() |> ignore
} catch {
_ => ()
}
Expand All @@ -64,22 +64,22 @@ pub extern "js" fn Promise::all(promises : Array[Promise]) -> Promise = "(ps) =>

///|
/// Wraps each given `async fn` in a `Promise` and waits for all of them to resolve.
pub async fn async_all![T](ops : Array[async () -> T!]) -> Array[T] {
async_all_raw!!(ops.map(fn(op) { async fn!() { Value::cast_from(op!!()) } })).map(
pub async fn async_all![T](ops : Array[() -> T!Error + Async]) -> Array[T] {
async_all_raw!(ops.map(fn(op) { async fn!() { Value::cast_from(op!()) } })).map(
Value::cast,
)
}

///|
async fn async_all_raw!(ops : Array[async () -> Value!]) -> Array[Value] {
Promise::all(ops.map(Promise::unsafe_new)).wait!!().cast()
async fn async_all_raw!(ops : Array[() -> Value!Error + Async]) -> Array[Value] {
Promise::all(ops.map(Promise::unsafe_new)).wait!().cast()
}

///|
pub fn async_test(op : async () -> Unit!) -> Unit {
pub fn async_test(op : () -> Unit!Error + Async) -> Unit {
async_run(async fn() {
try {
op!!()
op!()
} catch {
e => {
println("ERROR in `async_test`: \{e}")
Expand Down
8 changes: 4 additions & 4 deletions src/js/async_deprecated.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ extern "js" fn async_wrap_ffi(
///|
#deprecated("use Promise::wait instead")
pub async fn async_wrap(op : AsyncOp) -> Value! {
suspend!!(fn(k, ke) { async_wrap_ffi(op, k, fn(e) { ke(Error_(e)) }) })
suspend!(fn(k, ke) { async_wrap_ffi(op, k, fn(e) { ke(Error_(e)) }) })
}

///|
#deprecated("use Promise::new instead")
pub fn async_unwrap[T](op : async () -> T!) -> Promise {
Promise::new_ffi(fn() { Value::cast_from(op!!()) })
pub fn async_unwrap[T](op : () -> T!Error + Async) -> Promise {
Promise::new_ffi(fn() { Value::cast_from(op!()) })
}

///|
#deprecated("use Promise::unsafe_new instead")
pub fn Promise::new[T](op : async () -> T!) -> Promise {
pub fn Promise::new[T](op : () -> T!Error + Async) -> Promise {
Promise::unsafe_new(op)
}
6 changes: 3 additions & 3 deletions src/js/async_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ async fn op1() -> String? {

///|
async fn op2() -> String? {
guard op1!!() is Some(prefix)
guard op1!() is Some(prefix)
Some(prefix + ", World")
}

Expand All @@ -18,7 +18,7 @@ async fn op3() -> String? {
test "Promise::wait" {
@js.async_test(fn!() {
// Promise::unsafe_new + Promise::wait is a noop.
let res = @js.Promise::unsafe_new(fn() { op1!!() }).wait!!()
let res = @js.Promise::unsafe_new(fn() { op1!() }).wait!()
assert_eq!(res.cast(), Some("Hello"))
})
}
Expand All @@ -27,7 +27,7 @@ test "Promise::wait" {
test "async_all" {
@js.async_test(fn!() {
assert_eq!(
@js.async_all!!([fn() { op2!!() }, fn() { op1!!() }, fn() { op3!!() }]),
@js.async_all!([fn() { op2!() }, fn() { op1!() }, fn() { op3!() }]),
[Some("Hello, World"), Some("Hello"), None],
)
})
Expand Down