Spec-Zone.ru › Nim

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API