N予備校「プログラミング入門Webアプリ」を受講しています。
今回は第三章10,11節です。
同期・非同期処理
Node.jsは非同期で処理が実行される。
for (let count = 0; count < 500; count++) {
fs.appendFile(fileName, 'あ', 'utf8', () => {
fs.appendFile(fileName, 'い', 'utf8', () => {
fs.appendFile(fileName, 'う', 'utf8', () => {
fs.appendFile(fileName, 'え', 'utf8', () => {
fs.appendFile(fileName, 'お', 'utf8', () => {
fs.appendFile(fileName, '\n', 'utf8', () => {});
});
});
});
});
});
}
「あいうえお」を順番に出力しようとするとネストが深くなる。
一見うまくいきそうだけれど、1回目のループで行われるfs.appendFile(fileName, 'あ', 'utf8', () => {}
と2回目のループで行われるappendFile
は非同期なので、うまくいかない。
これは解説を聞いて、なるほどと思った。
Promise
非同期に実行される未来の結果を表すオブジェクト
const waitPromise = new Promise((resolve, reject) => {
setTimeout(() => resolve(), 1000); //1秒まってresolveを実行
});
waitPromise.then(() => console.log('hoge'));
console.log('fuga');
Promise
はあくまでオブジェクトで、then
のあとに実行したい処理を書く。そして、console.log('hoge')
が引数のresolve
に入る。
Promiseチェーン
new Promise((resolve) => {
const nowDate = new Date();
resolve(nowDate);
}).then((v1) => {
//v1は現在時刻
new Promise((resolve) => {
const monthAndDate = {
month: v1.getMonth(),
date: v1.getDate()
}
resolve(monthAndDate);
}).then((v2) => {
//v2 は 日付の情報
new Promise((resolve) => {
const text = `今日は${v2.month+1}月${v2.date}日です。`;
resolve(text);
}).then((v3) => {
// v3 は日付を示す文章
console.log(v3); // 今日の日付に関する文章が出力される
});
});
});
正直わかりにくすぎて混乱します。
resolve(nowDate)
の内容がthen
以下になると。
最終的にconsole.log(v3)
がresolve(nowDate)
の処理になる。
async/await
非同期処理を同期的に動かせる。 async function内でしか awaitは使えない。
function appendFilePromise(fileName, str){
return new Promise((resolve) =>{
fs.appendFile(fileName, str, 'utf8', ()=> resolve());
});
}
async function main(){
for(let count = 0; count < 500; count++){
await appendFilePromise(fileName, 'あ');
await appendFilePromise(fileName, 'い');
await appendFilePromise(fileName, 'う');
await appendFilePromise(fileName, 'え');
await appendFilePromise(fileName, 'お');
await appendFilePromise(fileName, '\n');
}
}
main();
わかりやすい。
botに登録したデータの読み書き
今回はJSONファイルに出力
JSON : JavaScriptで扱うオブジェクトや配列の書き方の形式
/**
* 登録された言葉を保存する
*/
function saveWords(){
fs.writeFileSync(fileName, JSON.stringify(praiseWords), 'utf8');
}
JSON.stringify
で配列をJSON形式に変換
try{
const data = fs.readFileSync(fileName, 'utf8');
praiseWords = JSON.parse(data);
}catch(ignore){
console.log(fileName + 'から復元できませんでした');
}
JSON.parse
でJSONから配列に変換。
fs.unlink(fileName, err =>{
//削除した後の処理
})
自分が作ったbotでは使わなかったけど削除処理。
まとめ
Promiseチェーンの理解はちょっとあやふや。
async/awaitが使えるならそっちをできるだけ使いたい。
さて、今回でbot作成は終了。
次からhttpサーバーの節に入ります。