#初めに
nodeで複数回使う処理をモジュール化して利用する際に非同期処理をすることができずに詰まったのでその解決方法の備忘録です。
#環境
node: v10.14.2
express: 4.16.0
#発生していた問題
main.js
//express の基本的なコードは省略しています
const Check = require('./check.js'); //moduleの読み込み
router.get('/', async function (req, res) {
let result = await Check(req.session.authentication, req.session.user);
if (result[0]) {
console.log("result[0] = ture")
}else{
console.log("authenticationデータが正しくありません")
}
Check.js
const express = require('express');
const Users = require('../models/user'); //dbの読み込み
module.exports = (authentication, user) => {
console.log("Check_1")
if (!authentication || !user) {
console.log("値が存在しません");
return false;
} else {
Users.findOne({
where: {
systemid: user
}
}).then((result) => {
if (authentication == result.session) {
console.log("認証成功");
return [true, result]
} else {
console.log("認証失敗");
return [false, null];
}
})
}
}
上記のコードを走らせると予想されログの出る順番は
check_1
認証成功
result[0] = true
だが実際には下記ログが出る
check_1
UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined
認証成功
async await で非同期にしているにもかかわらず非同期になっていないのが問題
#原因と解決
Check.js
const express = require('express');
const Users = require('../models/user'); //dbの読み込み
module.exports = async (authentication, user) => {
console.log("Check_1")
if (!authentication || !user) {
console.log("値が存在しません");
return false;
} else {
let result = await Users.findOne({
where: {
systemid: user
}
}) //.then((result) => {
if (authentication == result.session) {
console.log("認証成功");
return [true, result]
} else {
console.log("認証失敗");
return [false, null];
}
})
}
}
原因はCheckの処理で.thenををつかっていたことが原因だった。
実際の動きを理解しているわけではないがおそらく.thenをつかったモジュールをasync await で非同期に処理しようとしたことが原因ではないかと考えられる。
そのため.thenの記述をなくしasync await で処理すれば問題なくなった。
#終わりに
.thenで揃えたらどのような挙動になるか試していないので機会があれば試してこの記事に加筆しようと思う。