Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go and Node.js: a comparison

Go and Node.js: a comparison

Nathan Youngman

February 07, 2019
Tweet

More Decks by Nathan Youngman

Other Decks in Programming

Transcript

  1. – Brendan Eich “It was also an incredible rush job…

    I knew there would be mistakes, and there would be gaps, so I made it very malleable as a language.” “a language that was approachable, that you could put directly in the web page”
  2. – Ryan Dahl “JavaScript plus asynchronous IO plus some HTTP

    server stuff would be a cool thing. And I was so excited about that idea that I just worked on it non- stop for the next four years.”
  3. – Ryan Dahl, creator of Node.js “if you’re building a

    server, I can’t imagine using anything other than Go”
  4. – TJ Holowaychuk, creator of Express.js “If you’re doing distributed

    work then you’ll find Go’s expressive concurrency primitives very helpful.”
  5. Go origins • Unix • grep • UTF-8 encoding Ken

    Thompson Robert Griesemer • Strongtalk VM • Java HotSpot VM • Codegen for V8 Rob Pike • First window system for Unix • Newsqueak, Limbo (CSP)
  6. – Rob Pike “We wanted a language with the safety

    and performance of statically compiled languages such as C++ and Java, but the lightness and fun of dynamically typed interpreted languages such as Python.”
  7. • GCC toolchain Ian Lance Taylor Early gophers Brad Fitzpatrick

    Russ Cox • Memcached • OpenID • Bell Labs • Tech lead
  8. Async/Await const axios = require("axios");
 
 async function fetchHumans(url) {


    const response = await axios.get(url);
 return response.data;
 }
  9. Calling an async function const express = require("express");
 const app

    = express();
 const url = “https://www.google.com/humans.txt";
 const port = 3000; 
 app.get("/", async (req, res) => {
 const data = await fetchHumans(url);
 res.send(data);
 });
 
 app.listen(port, () => {
 console.info(`Listening on ${port}`);
 });
  10. Promises all the way down Whoops!
 app.get("/", async (req, res)

    => {
 const data = await fetchHumans(url);
 res.send(data);
 }); The result: Promise { <pending> }
  11. Multiple promises const urls = [
 "https://www.google.com/humans.txt",
 "https://www.netflix.com/humans.txt",
 "https://medium.com/humans.txt",
 ];


    
 app.get("/", async (req, res) => {
 const promises = urls.map((url) => fetchHumans(url));
 const data = await Promise.all(promises);
 res.setHeader("content-type", "text/plain");
 res.send(data.join("\n\n"));
 });
  12. We need error handling const url = "https://www.moogle.com/humans.txt"; The result:

    UnhandledPromiseRejectionWarning
 Error: connect ECONNREFUSED
  13. Try/Catch app.get("/", async (req, res) => {
 try {
 const

    data = await fetchHumans(url);
 res.send(data);
 } catch (err) {
 console.error(err.message);
 res.status(502).send("Bad gateway");
 }
 });
  14. First error app.get("/", async (req, res) => {
 try {


    const promises = urls.map((url) => fetchHumans(url));
 const data = await Promise.all(promises);
 res.setHeader("content-type", "text/plain");
 res.send(data.join("\n\n"));
 } catch (err) {
 console.error(err.message);
 res.status(502).send("Bad gateway");
 }
 });
  15. It looks synchronous package main
 
 import (
 "io"
 "log"


    "net/http"
 )
 
 func fetch(url string) (string, error) {
 r, err := http.Get(url)
 if err != nil {
 return "", err
 }
 defer r.Body.Close()
 b, err := ioutil.ReadAll(r.Body)
 if err != nil {
 return "", err
 }
 return string(b), nil
 }
  16. Response writer const url = "https://www.google.com/humans.txt"
 
 func handler(w http.ResponseWriter,

    req *http.Request) {
 data, err := fetch(url)
 if err != nil {
 log.Print(err)
 w.WriteHeader(http.StatusBadGateway)
 io.WriteString(w, "Bad gateway")
 return
 }
 io.WriteString(w, data)
 }
  17. Listen and serve func main() {
 http.HandleFunc("/", handler)
 
 const

    addr = ":3000"
 log.Printf("Listening on %v", addr)
 log.Fatal(http.ListenAndServe(addr, nil))
 }

  18. Fetch multiple humans.txt package main
 
 import (
 "io"
 "io/ioutil"


    "log"
 "net/http"
 "strings"
 "sync"
 )
 
 var urls = []string{
 "https://www.google.com/humans.txt",
 "https://www.netflix.com/humans.txt",
 "https://medium.com/humans.txt",
 }

  19. A synchronous API func handler(w http.ResponseWriter, req *http.Request) {
 data,

    err := fetchHumans(urls)
 if err != nil {
 log.Print(err)
 w.WriteHeader(http.StatusBadGateway)
 io.WriteString(w, "Bad gateway")
 return
 } 
 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
 io.WriteString(w, strings.Join(data, "\n\n"))
 }

  20. Concurrency primitives func fetchHumans(urls []string) ([]string, error) {
 var m

    sync.Mutex
 var wg sync.WaitGroup
 errChan := make(chan error, 1) 
 resp := make([]string, len(urls))
  21. for index, url := range urls {
 wg.Add(1)
 go func(index

    int, url string) {
 defer wg.Done()
 
 s, err := fetch(url)
 if err != nil {
 select {
 case errChan <- err:
 default:
 }
 return
 }
 m.Lock()
 resp[index] = s
 m.Unlock()
 }(index, url)
 }
 wg.Wait()
 
 select {
 case err := <-errChan:
 return nil, err
 default:
 }
 return resp, nil
 }
  22. Destructuring const data = {
 latitude: 53.5458874,
 longitude: -113.5034304,
 timezone:

    "America/Edmonton",
 currently: {
 summary: "Light Snow",
 temperature: 20.33,
 },
 };
 
 const {
 currently: {summary, temperature},
 } = data;
 
 console.info(`${summary} and ${temperature}ºF`);

  23. – Brendan Eich on early feature requests “I’d like to

    compare a number to a string that contains that numeral. And I don’t want to have to change my code to convert the string to a number, or the number to a string. I just want it to work. Can you please make the equals operator just say, Oh this looks like a two, and this looks like a string number two. They’re equal enough.”
  24. Incomparable if "2" == 2 {
 //
 } The result:

    invalid operation: "2" == 2 (mismatched types string and int)
  25. – Go brand book “Go is an open source programming

    language that enables the production of simple, efficient, and reliable software at scale.”
  26. Mutable iteration variables for index, url := range urls {


    go func(index int, url string) {
 // ..
 }(index, url)
 }
  27. JavaScript Go Dynamically typed Statically typed Lenient Strict compiler Prototypes,

    Classes, Inheritance Types, methods, interfaces First-class functions First-class functions Language
  28. Node.js Go prettier gofmt eslint go lint, go vet Babel,

    TypeScript go build Jest, Chai, Mocha, Jasmine go test Tooling
  29. Node.js Go Full stack Server-only* Ecosystem Batteries included Small projects*

    Large projects, large teams I/O bound CPU bound and I/O bound Malleable language Reliability, security Use when