nuxt-ts day6:TypeScript Deep Dive を読む 2
2020-12-05
# diary6日目。今日も座学。
https://typescript-jp.gitbook.io
知らなかったことをメモしていく。今日はlet
から宣言空間まで。
let
var foo = 123;
if (true) {
var foo = 456;
}
console.log(foo); // 456
JavaScriptにおいてvar
変数は関数スコープ(function scope)であり、{
は新しい変数スコープ(variable scope)を作成しない。
var
の代わりにlet
を使うと、スコープの外側で定義されているかもしれない変数とは異なる、真にユニークな変数を得ることができる。
let foo = 123;
if (true) {
let foo = 456;
}
console.log(foo); // 123
const
const の意外なメリット。可読性とメンテナンス性のどちらの面でも良いこと。
// 可読性が低いコードです
if (x > 10) {
}
// このほうがベターです
const maxRows = 10;
if (x > maxRows) {
}
この観点は無かったけど、確かにこれはそうかも。
とりあえずlet
とconst
を使っておけば幸せになれるということらしい。
for...of
var someArray = [9, 2, 5];
for (var item of someArray) {
console.log(item);
}
// ts -> js にトランスパイル //
for (var _i = 0; _i < someArray.length; _i++) {
var item = someArray[_i];
console.log(item);
}
これは楽そうだ。
Promise
JSON
を読むコードでPromise
を理解する
import fs = require('fs');
function readFileAsync(filename: string): Promise<any> {
return new Promise((resolve,reject) => {
fs.readFile(filename,(err,result) => {
if (err) reject(err);
else resolve(result);
});
});
}
function loadJSONAsync(filename: string): Promise<any> {
return readFileAsync(filename)
.then(function (res) {
return JSON.parse(res);
});
}
// 正しいjsonファイル
loadJSONAsync('good.json')
.then(function (val) { console.log(val); })
.catch(function (err) {
console.log('good.json error', err.message); // 呼び出されない
})
// 存在しないjsonファイル
.then(function () {
return loadJSONAsync('absent.json');
})
.then(function (val) { console.log(val); }) // 呼び出されない
.catch(function (err) {
console.log('absent.json error', err.message);
})
// 正しくないjsonファイル
.then(function () {
return loadJSONAsync('invalid.json');
})
.then(function (val) { console.log(val); }) // 呼び出されない
.catch(function (err) {
console.log('bad.json error', err.message);
});
この関数がよりシンプルになった理由は、"loadFile(async)+JSON.parse(sync) => catch"の連結をPromiseチェーンによって行ったためです。また、コールバックは我々ではなくPromiseチェーンによって呼び出されるので、コールバックをtry/catchで囲んでしまう誤りが起きる可能性はありませんでした。
並列制御フロー(Parallel control flow)
複数の非同期処理を実行し、すべてのタスクが終わったタイミングで何らかの処理を行いたいケースについて
// 何らかのデータをサーバから読み込むことを再現する処理
function loadItem(id: number): Promise<{ id: number }> {
return new Promise((resolve) => {
console.log('loading item', id);
setTimeout(() => { // サーバーからのレスポンス遅延を再現
resolve({ id: id });
}, 1000);
});
}
// Promiseチェーン
let item1, item2;
loadItem(1)
.then((res) => {
item1 = res;
return loadItem(2);
})
.then((res) => {
item2 = res;
console.log('done');
}); // 全体で 2秒 かかる
// 並列処理
Promise.all([loadItem(1), loadItem(2)])
.then((res) => {
[item1, item2] = res;
console.log('done');
}); // 全体で 1秒 かかる
これは便利そう!
firestore
とかAPIとの疎通で利用できそうだ。
今日はここまで。