紀錄一下在 javascript 如何建立一個 function ,於多個 Response 的資料都取完後才執行。
下面範例都是執行以下3個 request
URL | Parameter | Method |
---|---|---|
/get |
a=b&a=c&b=d |
GET |
/post |
a=b&a=c&b=d |
POST |
/anything |
POST |
首先是最傳統的 ajax (為了方便,直接以 jQuery 來寫)
var i = 0
function callback(){
if(i >= 3){
// do something after all request finish
}
i++
}
$.get("/get", "a=b&a=c&b=d", callback)
$.post("/post", "a=b&a=c&b=d", callback)
$.post("/anything", callback)
之後我發現自 jQuery v1.5 , jQuery 追加了 when() function ,可以以以下方式來做到(為了方便, debug log 第幾個 request)
$.when(
$.get("/get", "a=b&a=c&b=d", function(){console.debug(1)}),
$.post("/post", "a=b&a=c&b=d", function(){console.debug(2)}),
$.post("/anything", function(){console.debug(3)})
).then(function(){
// do something after all request finish
console.log('done')
})
之後 js 又追加 Promise 和 fetch() 這兩API
參照 Waiting for multiple all API responses to complete with the vanilla JS Promise.all() method 這篇文章,可以用以下寫法:
Promise.all([
fetch('/get?a=b&a=c&b=d'),
fetch(
'/post',
{
method: "POST",
body: (function(){
var f = new FormData
f.append("a", "b")
f.append("a", "c")
f.append("b", "d")
return f
})()
}
),
fetch(
"/anything",
{
method: "POST"
}
)
]).then(function (responses) {
// Get a JSON object from each of the responses
return Promise.all(responses.map(function (response) {
return response.text();
}));
}).then(function (data) {
// do something after all request finish
}).catch(function (error) {
// if there's an error, log it
console.log(error);
});
順帶一提,第二條 fetch()
也能寫成
fetch(
'/post',
{
method: "POST",
body: "a=b&a=c&b=d",
header: {
"Content-Type": "application/x-www-form-urlencoded"
}
}
)
如果不想用 fetch()
,可以參照《JavaScript Promise 全介紹》這篇文章,先建立 AJAX 的 Promise
function ajax(url, parameter, method = "GET") {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.addEventListener("readystatechange", function(e) {
switch(this.readyState){
case XMLHttpRequest.DONE:
resolve(JSON.parse(this.response))
break
case XMLHttpRequest.UNSENT:
reject(new Error(xhr))
break
}
})
if(typeof parameter == "string" && method.toUpperCase() != "GET"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.send(parameter)
}else if(method.toUpperCase() != "GET"){
xhr.send(parameter)
}else{
xhr.send()
}
});
}
然後用Promise.all()
(一樣,為了方便,debug log 第幾個 request):
Promise.all([
ajax("/get", "a=b&a=c&b=d").then((data)=>{console.debug(1); return data}),
ajax("/post", "a=b&a=c&b=d", "POST").then((data)=>{console.debug(2); return data}),
ajax("/anything", null, "POST").then((data)=>{console.debug(3); return data})
]).then(function(datas){
// do somthing
console.log(datas)
})
沒有留言:
張貼留言