Last active
October 7, 2023 22:36
-
-
Save danielsan/0fe5de4a4e1842fe34b67b2499ad91c5 to your computer and use it in GitHub Desktop.
Example of sequential calls vs concurrent calls in Javascript. It will work in nodejs18.x or greater or latest versions of chrome/chromium browsers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"net/http" | |
"sync" | |
"time" | |
) | |
type Result struct { | |
I int `json:"i"` | |
URL string `json:"url"` | |
Obj string `json:"obj"` | |
} | |
func main() { | |
urls := []string{ | |
"comments/1","comments/2", | |
"posts/1", "posts/2", | |
"albums/1", "albums/2", | |
"photos/1", "photos/2", | |
"todos/1", "todos/2", | |
"users/1", "users/2", | |
} | |
startTime := time.Now() | |
for i, url := range urls { | |
result := getResult(url) | |
result.I = i | |
result.URL = url | |
fmt.Println(result) | |
} | |
elapsedTime := time.Since(startTime) | |
fmt.Printf("sequentially: %v\n", elapsedTime) | |
startTime = time.Now() | |
var wg sync.WaitGroup | |
wg.Add(len(urls)) | |
results := make([]Result, len(urls)) // | |
for i, url := range urls { | |
go func(i int, url string) { | |
defer wg.Done() | |
result := getResult(url) | |
result.I = i | |
result.URL = url | |
results[i] = result | |
}(i, url) | |
fmt.Println("calles asyc #%n", i) | |
} | |
wg.Wait() | |
for _, result := range results { | |
fmt.Println(result) | |
} | |
elapsedTime = time.Since(startTime) | |
fmt.Printf("concurrently: %v\n", elapsedTime) | |
} | |
func getResult(url string) Result { | |
resp, err := http.Get("https://jsonplaceholder.typicode.com/" + url) | |
if err != nil { | |
panic(err) | |
} | |
defer resp.Body.Close() | |
body, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
panic(err) | |
} | |
var obj map[string]interface{} | |
err = json.Unmarshal(body, &obj) | |
if err != nil { panic(err) } | |
objName := "unknown" | |
if constructor, ok := obj["constructor"].(map[string]interface{}); ok { | |
if name, ok := constructor["name"].(string); ok { | |
objName = name | |
} | |
} | |
return Result{Obj: objName} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Example of sequential calls vs concurrent calls in Javascript. | |
* It will work in nodejs18.x or greater | |
* In latest versions of chrome/chromium browsers you can run it in the console | |
* just head to https://jsonplaceholder.typicode.com/ and paste the code | |
**/ | |
const urls = [ | |
'comments/1', 'comments/2', | |
'posts/1', 'posts/2', | |
'albums/1', 'albums/2', | |
'photos/1', 'photos/2', | |
'todos/1', 'todos/2', | |
'users/1', 'users/2', | |
] | |
let approach = 'sequentially' | |
console.time(approach) | |
let i = -1 | |
for (let i = 0; i < urls.length; i++) { | |
const url = urls[i] | |
const result = await fetch(`https://jsonplaceholder.typicode.com/${url}`) | |
.then(response => response.json()) | |
.then(obj => ({ i, url, obj: obj?.constructor?.name })) | |
console.log(result) | |
} | |
console.timeEnd(approach) | |
approach = 'concurrently' | |
console.time(approach) | |
// since I know the final size this is faster than push | |
const promises = new Array(urls.length) | |
for (let i = 0; i < urls.length; i++) { | |
const url = urls[i] | |
promises[i] = fetch(`https://jsonplaceholder.typicode.com/${url}`) | |
.then(response => response.json()) | |
.then(obj => ({ i, url, obj: obj?.constructor?.name })) | |
} | |
const results = await Promise.all(promises) | |
for (const result of results) { | |
console.log(result) | |
} | |
console.timeEnd(approach) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment