日記
風邪が長引いてランニングも勉強もちょっとさぼりぎみ。
ぐうたら寝てばかり。
こういう時期ってあるよね。
前回の続き
前回、以下の処理をcallback関数を使って実現しました。
www.tohuandkonsome.site
- ファイルを読み込む
- 読み込んだファイルの内容のチェックをする
- チェックが通れば、
/sample
にGETリクエストを飛ばす
- 上記のリクエストが終わったら、
/other
にリクエストを飛ばす
実際、書いてみると、どの処理が実行されるのかがわかりにくい、という問題を実感することができました。
なので、Promiseを使って書き直したいと思います。
前回のファイル読み込み
前回は、こんな感じでファイルを読み込むReadFile
関数を作成していました。
ファイル読み込みが終わった後の処理は、callback関数を渡すことで実現していました。
ReadFile.js(Promise使用前)
module.exports = function(file, callback){
let reader = new FileReader();
reader.onload = function(){
text = reader.result
callback(text)
}
reader.readAsText(file)
}
ReadFile.js
を実際に使っている処理はこんな感じでした。
app.js
onDrop:function(event){
let file = event.target.files[0];
const callback = function(text){
let count = (text.match(new RegExp('おはんき','g')) || []).length
if(count > 0){
}
}
let text = ReadFile(file, callback);
},
Promiseを使ったファイル読み込み
さっそくPromiseを使ってみます。
といっても簡単で、Promiseオブジェクトを返すようにしてあげるだけです。
実際の処理は、Promiseオブジェクトの引数として書きます。
処理が正常に終わったときにresolve()
を書いてあげます。
処理がエラーの場合はreject()
を書くのですが、今回は面倒なので省略しちゃってます。
ReadFile.js(Promise使用)
module.exports = function(file){
return new Promise(function(resolve, reject){
let reader = new FileReader();
reader.onload = function(){
let text = reader.result
resolve(text);
}
reader.readAsText(file)
})
}
上記の関数を実際に呼んでみます。
以下のように、ReadFile
を呼んだ後に.then()
と.catch()
を使います。
app.js
onDrop:function(event){
let file = event.target.files[0];
ReadFile(file)
.then((text) =>{
console.log(text);
})
.catch((error) =>{
console.log(error);
});
},
.then()
はReadFile
関数内でresolve
した場合に実行される処理を書きます。
一方、.catch
はReafFile
関数内でreject
した場合に呼ばれる処理になります。
ファイルのチェック
ファイルのチェックは、以下のように.then()
に続けて書くこともできます。
ですが、ここではファイルのチェック処理もPromiseを使うことで、さらに見通しをよくしようと思います。
app.js
onDrop:function(event){
let file = event.target.files[0];
ReadFile(file)
.then((text) =>{
})
.catch((error) =>{
console.log(error);
});
},
まず、ファイルのチェック処理もファイル読み込みと同様の形でモジュール化しておきます。
Validate.js
module.exports = function(text){
return new Promise(function(resolve, reject){
let count = (text.match(new RegExp('おはんき','g')) || []).length
if(count > 0){
resolve();
}else{
reject('ファイルの内容がおかしいよ');
}
})
}
そうしたら、以下のようにReafFile
関数の.then()
内で呼ぶことにします。
app.js
onDrop:function(event){
let file = event.target.files[0];
ReadFile(file)
.then((text) =>{
return Validate(text);
})
.then(() =>{
})
.catch((error) =>{
console.log(error);
});
},
ポイントは、Validate
ではなく return Validate
するところになります。
Promiseオブジェクトをreturnしないとその後のthen()
が順番通りに動いてくれません。
サーバーにリクエストを投げる
ここまでくると後は作業になります。
前回作ったXhr.js
もPromiseを使います。
こんな感じにしました。
Xhr.js
module.exports = function(url){
return new Promise(function(resolve, reject){
var xhr= new XMLHttpRequest();
xhr.open("GET", url);
xhr.send();
xhr.onload = function(){
if(xhr.readyState === 4 && xhr.status === 200) {
resolve(xhr.responseText);
}else{
reject('リクエストに失敗しているよ');
}
};
})
}
使う際も以下のような形になります。
app.js
onDrop:function(event){
let file = event.target.files[0];
ReadFile(file)
.then((text) =>{
return Validate(text);
})
.then(() =>{
return Xhr('/sample');
})
.then((text) =>{
console.log(text);
return Xhr('/other');
})
.then((text) =>{
console.log(text);
})
.catch((error) =>{
console.log(error);
});
},
これで、上から下に処理が流れるということが前回よりもだいぶはっきりしました!
サーバーリクエストにaxiosを使う
axiosはPromiseオブジェクトを返す便利なAjaxリクエストができるモジュールになります。
使い方も、今まで使っていたXhr.js
を置き換える以下のように置き換えるだけで使うことができます。
app.js
onDrop:function(event){
let file = event.target.files[0];
ReadFile(file)
.then((text) =>{
return Validate(text);
})
.then(() =>{
return axios.get('/sample');
})
.then((text) =>{
console.log(text);
return axios.get('/other');
})
.then((text) =>{
console.log(text);
})
.catch((error) =>{
console.log(error);
});
},
だいぶなげやりな感じになってしまいましたが、なんとなくPromiseを使うことができるようになりました!
この調子でasync/awaitも使えるようになりたいですね!