std/asyncjs
Источник РедактироватьЭтот модуль реализует типы и макросы для написания асинхронного кода для бэкэнда JS. Он предоставляет инструменты для взаимодействия с JavaScript API-интерфейсами и библиотеками асинхронных операций, написания асинхронных процедур на Nim и преобразования кода, основанного на обратных вызовах, в промисы.
Процедура Nim является асинхронной, когда она включает псевдоним {.async.}. Она всегда должна иметь тип возвращаемого значения Future[T] или не иметь типа возвращаемого значения вообще. По умолчанию предполагается тип возвращаемого значения Future[void].
Это примерно эквивалентно ключевому слову async в коде JavaScript.
proc loadGame(name: string): Future[Game] {.async.} =
# code должно быть эквивалентно
async function loadGame(name) {
// code
} Вызов асинхронной процедуры обычно требует await для ожидания завершения Future.
var game = await loadGame(name)
Часто вы можете работать с API-интерфейсами, основанными на обратных вызовах. Вы можете обернуть их асинхронными процедурами, используя промисы и newPromise:
proc loadGame(name: string): Future[Game] =
var promise = newPromise() do (resolve: proc(response: Game)):
cbBasedLoadGame(name) do (game: Game):
resolve(game)
return promise Прямые определения работают корректно, вам просто нужно всегда добавлять псевдоним {.async.}:
proc loadGame(name: string): Future[Game] {.async.} Совместимость с JavaScript
В настоящее время Nim генерирует async/await код JavaScript, который поддерживается в современных EcmaScript и большинстве современных версий браузеров, Node.js и Electron. Если вам нужно использовать этот модуль со старыми версиями JavaScript, вы можете использовать инструмент, который создает обратные порты результирующего кода JavaScript, например, babel.
Импорты
- jsffi, макросы, с момента
Типы
Error {.importjs: "Error".} = ref object of JsRoot message*: cstring name*: cstring- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error Источник Редактировать
Future[T] = ref object future*: T
- Источник Редактировать
OnReject = proc (reason: Error)
- Источник Редактировать
PromiseJs {.importjs: "Promise".} = ref object- Источник Редактировать
Процедуры
proc catch[T](future: Future[T]; onReject: OnReject): Future[void]
- См. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
Пример: cmd: -r:off
from std/sugar import `=>` from std/strutils import contains proc fn(n: int): Future[int] {.async.} = if n >= 7: raise newException(ValueError, "foobar: " & $n) else: result = n * 2 proc main() {.async.} = var reason: Error await fn(6).catch((r: Error) => (reason = r)) # note: `()` are needed, `=> reason = r` would not work assert reason == nil await fn(7).catch((r: Error) => (reason = r)) assert reason != nil assert "foobar: 7" in $reason.message discard main()Источник Редактировать proc newPromise(handler: proc (resolve: proc ())): Future[void] {. importjs: "(new Promise(#))", ...raises: [], tags: [], forbids: [].}- Помощник для обертывания функций, основанных на обратных вызовах, в промисы и асинхронные процедуры. Источник Редактировать
proc newPromise[T](handler: proc (resolve: proc (response: T))): Future[T] {. importjs: "(new Promise(#))", ...raises: [], tags: [], forbids: [].}- Помощник для обертывания функций, основанных на обратных вызовах, в промисы и асинхронные процедуры. Источник Редактировать
proc then[T](future: Future[T]; onSuccess: proc; onReject: OnReject = nil): auto
- См. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then Возвращает
Futureиз типа возвращаемого значенияonSuccess(T.default).Пример: cmd: -r:off
from std/sugar import `=>` proc fn(n: int): Future[int] {.async.} = if n >= 7: raise newException(ValueError, "foobar: " & $n) else: result = n * 2 proc asyncFact(n: int): Future[int] {.async.} = if n > 0: result = n * await asyncFact(n-1) else: result = 1 proc main() {.async.} = block: # then assert asyncFact(3).await == 3*2 assert asyncFact(3).then(asyncFact).await == 6*5*4*3*2 let x1 = await fn(3) assert x1 == 3 * 2 let x2 = await fn(4) .then((a: int) => a.float) .then((a: float) => $a) assert x2 == "8.0" block: # then with `onReject` callback var witness = 1 await fn(6).then((a: int) => (witness = 2), (r: Error) => (witness = 3)) assert witness == 2 await fn(7).then((a: int) => (witness = 2), (r: Error) => (witness = 3)) assert witness == 3Источник Редактировать
Макросы
macro async(arg: untyped): untyped
- Макрос, который преобразует обычные процедуры в совместимые с JavaScript асинхронные процедуры. Источник Редактировать
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asyncjs.html