javascriptのfetchを使ってAPIより結果を取得
概要
fetch使ってみたい
APIはgo言語で作成した適当なやつ
サーバ側
package main import ( "encoding/json" "log" "math/rand" "net/http" "time" ) func main() { http.HandleFunc("/sample_api1", sampleAPI1) http.HandleFunc("/sample_api2", sampleAPI2) http.HandleFunc("/sample_api3", sampleAPI3) http.ListenAndServe("127.0.0.1:8080", nil) } // Response ... type Response struct { Status int `json:"status"` Rssult string `json:"result"` } func sampleAPI1(w http.ResponseWriter, r *http.Request) { //if r.Method == http.MethodOptions { // return //} log.Println("api1", r.Method) rand.Seed(time.Now().UnixNano()) time.Sleep(time.Duration(int(rand.Intn(5))) * time.Second) response := Response{http.StatusOK, "ok1"} res, _ := json.Marshal(response) r.Close = true defer r.Body.Close() w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "*") w.Header().Set("Accept", "application/json") w.Header().Set("Content-Type", "application/json") w.Write(res) } func sampleAPI2(w http.ResponseWriter, r *http.Request) { //if r.Method == http.MethodOptions { // return //} log.Println("api2", r.Method) rand.Seed(time.Now().UnixNano()) time.Sleep(time.Duration(int(rand.Intn(5))) * time.Second) response := Response{http.StatusOK, "ok2"} res, _ := json.Marshal(response) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "*") w.Header().Set("Content-Type", "application/json") w.Write(res) } func sampleAPI3(w http.ResponseWriter, r *http.Request) { //if r.Method == http.MethodOptions { // return //} log.Println("api3", r.Method) rand.Seed(time.Now().UnixNano()) time.Sleep(time.Duration(int(rand.Intn(5))) * time.Second) response := Response{http.StatusOK, "ok3"} res, _ := json.Marshal(response) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "*") w.Header().Set("Content-Type", "application/json") w.Write(res) }
やって置かないとポートが違うとかなんとかでCORSエラーで弾かれる
javascript(Promise.all)
unction taskA() { return fetch("http://127.0.0.1:8080/sample_api1", { method: "GET", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, cors, *same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, same-origin, *omit headers: { "Content-Type": "application/json; charset=utf-8", }, redirect: "manual", // manual, *follow, error referrer: "no-referrer", // no-referrer, *client //body: JSON.stringify("{}"), // 本文のデータ型は "Content-Type" ヘッダーと一致する必要があります }) .then(function(response) { console.log("taskA"); return response.json(); }); } function taskB() { return fetch("http://127.0.0.1:8080/sample_api2", { method: "GET", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, cors, *same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, same-origin, *omit headers: { "Content-Type": "application/json; charset=utf-8", }, redirect: "manual", // manual, *follow, error referrer: "no-referrer", // no-referrer, *client //body: JSON.stringify("{}"), // 本文のデータ型は "Content-Type" ヘッダーと一致する必要があります }) .then(function(response) { console.log("taskB"); return response.json(); }); } function taskC() { return fetch("http://127.0.0.1:8080/sample_api3", { method: "GET", // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, cors, *same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "same-origin", // include, same-origin, *omit headers: { "Content-Type": "application/json; charset=utf-8", }, redirect: "manual", // manual, *follow, error referrer: "no-referrer", // no-referrer, *client //body: JSON.stringify("{}"), // 本文のデータ型は "Content-Type" ヘッダーと一致する必要があります }) .then(function(response) { console.log("taskC"); return response.json(); }); } // 並列ですべて完了後にレスポンスを返却 console.log("start"); Promise.all([ taskA(), taskB(), taskC() ]).then(function(data) { console.log("result start"); console.log(data); console.log("result end"); }); console.log("end");
↓
start end taskB taskC taskA result start (3) [{…}, {…}, {…}]0: {status: 200, result: "ok1"}1: {status: 200, result: "ok2"}2: {status: 200, result: "ok3"}length: 3__proto__: Array(0) result end
※逐次処理も同じ感じで対応できそう
所感
今までajaxのcallbackでやってた部分が多いため、Promiseに対応していかないといけないが
ちょっと仕組みが難しく感じる
少しずつ確認して理解していくしかない…