Skip to content

Commit

Permalink
followup nim-lang#16871 asyncjs.then: allow pipelining procs returnin…
Browse files Browse the repository at this point in the history
…g futures
  • Loading branch information
timotheecour committed Feb 25, 2021
1 parent b725e0e commit 84634e1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/js/asyncjs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ macro async*(arg: untyped): untyped =
result.add generateJsasync(oneProc)
else:
result = generateJsasync(arg)
# echo result.repr # PRTEMP

proc newPromise*[T](handler: proc(resolve: proc(response: T))): Future[T] {.importcpp: "(new Promise(#))".}
## A helper for wrapping callback-based functions
Expand All @@ -156,6 +157,8 @@ proc newPromise*(handler: proc(resolve: proc())): Future[void] {.importcpp: "(ne
## A helper for wrapping callback-based functions
## into promises and async procedures.

# template `===>`(a)

when defined(nimExperimentalAsyncjsThen):
since (1, 5, 1):
#[
Expand All @@ -180,6 +183,10 @@ when defined(nimExperimentalAsyncjsThen):
## See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
asm "`result` = `future`.then(`onSuccess`, `onReject`)"

proc then*[T, T2](future: Future[T], onSuccess: proc(value: T): Future[T2], onReject: OnReject = nil): Future[T2] =
## See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
asm "`result` = `future`.then(`onSuccess`, `onReject`)"

proc then*[T](future: Future[T], onSuccess: proc(value: T), onReject: OnReject = nil): Future[void] =
## See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
asm "`result` = `future`.then(`onSuccess`, `onReject`)"
Expand Down Expand Up @@ -216,4 +223,5 @@ when defined(nimExperimentalAsyncjsThen):
assert "foobar: 7" in $reason.message
discard main()

# xxx add tests and examples for `then` with some `onReject` callback.
asm "`result` = `future`.catch(`onReject`)"
19 changes: 19 additions & 0 deletions tests/js/tasync.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ proc fn(n: int): Future[int] {.async.} =
else:
return 10

proc asyncFact(n: int): Future[int] {.async.} =
if n > 0: result = n * await asyncFact(n-1)
else: result = 1

proc asyncIdentity(n: int): Future[int] {.async.} =
if n > 0: result = 1 + await asyncIdentity(n-1)
else: result = 0

proc main() {.async.} =
block: # then
let x = await fn(4)
Expand All @@ -63,6 +71,17 @@ proc main() {.async.} =
let x2 = await fn(4).then((a: int) => (discard)).then(() => 13)
doAssert x2 == 13

let x4 = await asyncFact(3).then(asyncIdentity).then(asyncIdentity).then((a:int) => a * 7).then(asyncIdentity)
doAssert x4 == 3 * 2 * 7

when false:
# pending bug #17177
proc asyncIdentityNested(n: int): Future[int] {.async.} = return n
let x5 = await asyncFact(3).then(asyncIdentityNested)
doAssert x5 == 3 * 2
let x6 = await asyncFact(3).then((a:int) {.async.} => a * 11)
doAssert x6 == 3 * 2 * 11

block: # catch
var reason: Error
await fn(6).then((a: int) => (witness.add $a)).catch((r: Error) => (reason = r))
Expand Down

0 comments on commit 84634e1

Please sign in to comment.