
自称Javascriptマイスターを名乗っているんですが、たまに不具合の原因が見つけられずに数時間費やす事があります。
今回も仕事で締め切りが迫っているのに、3時間近くも悩みに悩んで、ようやく解決したけど、原因不明状態でモヤモヤしたので、
ブログに書いておきたいと思います。
事象
他社の仕事ソースのため、あまり細かなコードを載せるわけにはいかないのですが、
簡単に書くと次の様なコードを書きました。
async function (){
return {
data1 : await get_data1("foo"),
data2 : await get_data2("var"),
}
}
2つの種類の違うデータを、それぞれPHPからデータベーステーブルより取得する別の関数を、連想配列にして返す処理を書いていました。
ポイントは、async ~ await 処理にして、戻り値を待つ状態にしていたのですが、この関数が
returnされないという不具合が発生していました。
調査
調査ポイントは、データベースからデータ取得をする、SQLクエリ、PHPのAPIコード、Javascriptの "get_data1()" と "get_data2()" のそれぞれの関数。
これらを全てチェックして、おかしなところがないか探してみましたが、どれも正常。
ブレイクポイントなどをセットしてみても、それぞれ単体で処理されている事はわかった。(問題ないって事)
そして、先ほどのソースコードを分解してみました。
async function (){
const data1 = await get_data1("foo")
console.log("data1", data1)
const data2 = await get_data2("var")
console.log("data2", data2)
return {
data1 : data1,
data2 : data2,
}
}
このコードを実行したところ、data1は正常に表示(console.log)されて、data2は、表示されない状態が確認できました・・・
そして、さらに、次の様にdata1とdata2を逆にしてみたところ・・・
async function (){
const data2 = await get_data2("var")
console.log("data2", data2)
const data1 = await get_data1("foo")
console.log("data1", data1)
return {
data1 : data1,
data2 : data2,
}
}
data2が正常に表示されて、data1がコケていることが確認できました・・・
ナンテコッタ!!!
推測
このシステム、これまで似た様な処理をいくつか作ってきたんですが、この事象は初めてでした。
推測1. サーバーの受付が、2つ立て続けに受け付けられない
ローカルのdockerで開発をしているので、設定内部はよく熟知しているんですが、
そんな設定になっているのは確認できていません・・・
推測2. APIセッションが変わっている
もしこれであれば、APIの致命的なバグなのですが、複数のAPI読み込みは、他のコードでも書いているので、
これはそもそも疑う必要がないような気がします・・・
推測3. 非同期処理でレスポンスが競合している
もはや疑うところはココかな・・・と思いました。
解決(とりあえず)
async ~ await の処理を立て続けに書いているので、ここで何かしらの問題が起きていると思って、次の様なコードに直してみました。
async function (){
const [daata1, data2] = await Promise.all([
get_data1(uuid),
get_data2(uuid)
])
console.log("data1", data1)
console.log("data2", data2)
return {
data1 : data1,
data2 : data2,
}
}
Promise,All()で、まとめて処理をしてみると・・・
無事に2つとものデータの取得ができるようになりました。
あとがき
なんとも後味の悪い結果になり、モヤモヤが取れませんが、
async~awaitは、立て続けに書かないほうがいいというのが、いまのところの結論にしておきたいと思います。
では、引き続きデスマーチにトライします!
0 件のコメント:
コメントを投稿