From 84634e171b3a34717dd0fea89303a6bb2c6e9fd9 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 24 Feb 2021 14:00:36 -0800 Subject: [PATCH] followup #16871 asyncjs.then: allow pipelining procs returning futures --- lib/js/asyncjs.nim | 8 ++++++++ tests/js/tasync.nim | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/js/asyncjs.nim b/lib/js/asyncjs.nim index 45053fbaa923c..0599cde15d17c 100644 --- a/lib/js/asyncjs.nim +++ b/lib/js/asyncjs.nim @@ -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 @@ -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): #[ @@ -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`)" @@ -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`)" diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim index e676ba14b2c73..a667828652b64 100644 --- a/tests/js/tasync.nim +++ b/tests/js/tasync.nim @@ -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) @@ -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))