Javascriptのajax関数は非同期的に実行され、doneメソッドの中でレスポンスを処理するというのが一般的な使い方だと思います。
今回、このajaxのレスポンスをdoneメソッドで処理するのではなく、グローバル変数に格納する方法について共有したいと思います。
目次
通常のajaxの使い方
通常のajaxは下記のように記述すると思います。
doneメソッドの中にしか続きを書けないという制限があります。
const url = 'http://fuga.com'
$.ajax({
type : 'get',
url : url,
}).done(function(response){
//取得したresponseに対する処理
.
.
.
}).fail(function(error){
console.log(error)
})
ajaxの取得結果をグローバル変数に入れようとしてみる
Ajaxの結果をグローバル変数に入れようとしてみると、下記のようなコードを思いつきます。
しかしこれはうまく動きません。
result変数にはundefinedが入ってしまいます。
const url = 'http://fuga.com'
let result
$.ajax({
type : 'get',
url : url,
}).done(function(response){
result = response
}).fail(function(error){
console.log(error)
})
console.log(result) //undefined
ajaxの取得結果をグローバル変数に入れる正しいやり方
ajaxにはasyncオプションが用意されており、これをfalseにするとajaxが同期的に実行され取得結果をグローバル変数に入れることができるようになります。
先ほどのコードにasync : falseを追加するだけでOKです。
const url = 'http://fuga.com'
let result
$.ajax({
type : 'get',
url : url,
async : false, //追加
}).done(function(response){
result = response
}).fail(function(error){
console.log(error)
})
console.log(result) //ajaxの取得結果が入っている
ajaxの処理を関数としてまとめる
Ajaxは記述が長くなるので共通関数としてまとめると使いやすくなります。
手続き処理のコードがとてもすっきりしました。
const url = 'http://fuga.com'
response = getAjax(url, {'id':1})
if(response){
//取得が成功した時の処理
.
.
.
}
function getAjax(url, data=null) {
let result = null
$.ajax({
type : 'get',
url : url,
data : data,
async : false,
}).done(function(response){
result = response
}).fail(function(error){
console.log(error)
})
return result
}
上記の関数は取得に失敗した時は返り値としてnullを返し、エラー内容はコンソールに出力されます。
JSON.parseでのオブジェクトへの変換も自動で行う
ajaxではレスポンスとしてJSONを受け取り、JSON.parseでオブジェクトに変換して使うことがよくあると思います。
doneメソッドの中を以下のように修正することで、レスポンスがテキストの場合はそのまま、JSONの場合はJSON.parseして受け取ることができるので、より便利になります。
function getAjax(url, data=null) {
let result = null
$.ajax({
type : 'get',
url : url,
data : data,
async : false,
}).done(function(response){
try{ // 修正
result = JSON.parse(response) // 修正
}catch{ // 修正
result = response // 修正
} // 修正
}).fail(function(error){
console.log(error)
})
return result
}
POST用のajax共通関数も作っておく
最後にPOST用のajax関数も作成して終わりにしましょう。
getAjaxの処理をcallAjax関数として外に切り出して、getAjaxからもpostAjaxからも呼び出せる形にしました。
下記のような中身のファイルを用意しておけばどこからでもGETまたはPOSTでajaxを実行できて便利です。
function getAjax(url, data=null) {
return callAjax('get', url, data)
}
function postAjax(url, data) {
return callAjax('post', url, data)
}
function callAjax(type, url, data=null) {
let result = null
$.ajax({
type : type,
url : url,
data : data,
async : false,
}).done(function(response){
try{
result = JSON.parse(response)
}catch{
result = response
}
}).fail(function(error){
console.log(error)
})
return result
}
素のJavascriptバージョン
素のJavascriptで同様の事を行いたい場合の関数も載せておきます。
素のJavascriptでのajax通信はXMLHttpRequestクラスで行えます。
XMLHttpRequestクラスで同期通信を行いたい時はopenメソッドの第三引数をfalseにします。
function callAjax(type, url, data=null) {
let result = null
let params = new URLSearchParams( data ).toString()
let contentType = 'application/x-www-form-urlencoded'
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState != 4){ return }
if(xhr.status == 200){
try{
result = JSON.parse(xhr.responseText)
}catch{
result = xhr.responseText
}
} else {
console.log('XMLHttpRequestエラー' + xhr.status + ' : ' + xhr.statusText)
}
}
if(type == 'get'){
url = url + '?' + params
}
xhr.open(type, url, false)
xhr.setRequestHeader('Content-type', contentType)
xhr.send(params)
return result
}
以上、Ajaxの取得結果を変数に入れる方法でした!