Promises Tutorial by Irakli Nadareishvili
  • Introduction
  • Turning Callbacks Into Promises
  • Chain Parallel with Sequential
  • Conditions and Promises
  • Keeping Promise Chains Flat
  • Async and Await
  • Async/Await & Express, Mocha etc.
  • One More Thing (Go)...
  • One More Thing (Python)...
  • One More Thin (Nim)…
Powered by GitBook
On this page

Was this helpful?

One More Thin (Nim)…

PreviousOne More Thing (Python)...

Last updated 5 years ago

Was this helpful?

Now that we have seen how Go and Python would do it, let's take a look at the implementation in . This one is special because Nim is arguably a language that is a blend of Python and Go - it has very Python-like syntax, does type inference and cross-platform compilation of executable binaries like Go (maybe less streamlined for now). And it supports both async/await as well as "spawn" (coroutines) syntaxes.

As a reminder, in this example we are:

  1. Looking up a list of authors for the Microservices Architecture book, using Google Books API

  2. Looking up, in parallel, the number of books each author has published. This means issuing several concurrent API calls to Google books API, all at the same time.

  3. Waiting until all parallel lookups from #2 finish, since they can take different length of time, and when all of them are finished - printing out the results in a nicely-formatted way.

Chain Parallel with Sequential (Async/Await)

import httpclient, json, strformat, asyncdispatch, uri

const base_url = "https://www.googleapis.com/books/v1/volumes?q="

type
  Author* = object
   name*, uri*, count*: string

proc fetch(uri: string): Future[string] =
  echo fmt"Fetching: {uri}"
  var client = newAsyncHttpClient()
  result = client.getContent(uri) 

proc getAuthorsResults(authors: JsonNode) {.async.} =
  var authorsSeq = newSeq[Author](0) # empty at creation
  var lookups = newSeq[Future[string]](0)

  for authorJSON in authors:
    let author = authorJSON.getStr()
    let author_url = fmt"{base_url}inauthor:{encodeUrl(author)}"
    authorsSeq.add(Author(name: author, uri: author_url))
    lookups.add(fetch(author_url))

  var allResults =  await all(lookups)
  var c = 0
  for res in allResults:
    var rj = parseJson(res)
    var count = rj["totalItems"]
    echo fmt" {authorsSeq[c].name} - {count}"
    c.inc()


proc main() {.async.} =

  const msa_isbn = "1491956224"
  let   msa_url = fmt"{base_url}isbn:{msa_isbn}" # "Microservice Architecture"
  let response = await fetch(msa_url)

  let rj = parseJson(response)
  let authors = rj["items"][0]["volumeInfo"]["authors"]

  await getAuthorsResults(authors)


waitFor main()

# compile with:
# nim compile -d:ssl http.nim

Side note: full source code of this example can be found at:

Nim
https://github.com/inadarei/nim-async