🔧
TypeScriptのconstructorで非同期処理をしたくなったら
はじめに
TSのconstructorを書いていて、一部awaitで値をセットしようとしたらできませんでした。
ということで、初期化用の非同期メソッドを用意して、その中でawaitを使う処理を行うように変更して返すことにしました。
これ、よくやるのですが、たまに忘れるので備忘録として記事にしておこうと思います。
結論
- constructorにはasyncに利用できない
-
'async' modifier cannot appear on a constructor declaration.(1089)
が発生する
-
- 初期化時に非同期処理(外部APIをコールした結果を取得するなど)を行う際には、初期化用のメソッドを定義する
やってみたこと
constructorでawaitできない、という状況の再現
class Fruits {
name: string;
price: number;
constructor( name:string ){
this.name = name;
this.price = await this.setPrice();
}
private async setPrice(){
return setTimeout( () => { Math.floor(Math.random() * 100 ) }, 3000); // 時間がかかる処理;
}
}
const main = async() => {
const apple = new Fruits('apple');
console.log( apple.price );
}
main();
Playground Link
constructorにasyncがないので、当然awaitは使えません。 'await' expressions are only allowed within async functions and at the top levels of modules.(1308)
が出ます。
では、constructorにasyncをつければいいのでは?と思ったのでやってみます。
class Fruits {
name: string;
price: number;
async constructor( name:string ){
this.name = name;
this.price = await this.setPrice();
}
private async setPrice(){
return setTimeout( () => { Math.floor(Math.random() * 100 ) }, 3000); // 時間がかかる処理;
}
}
const main = async() => {
const apple = new Fruits('apple');
console.log( apple.price );
}
main();
Playground Link
constructorにはasyncを使えません。コレだと 'async' modifier cannot appear on a constructor declaration.(1089)
が出ます。
初期化用のメソッドを用意する場合
class Fruits {
name: string;
price: number;
constructor(){
this.name = "";
this.price = 0;
}
public static async build( name:string ): Promise<Fruits>{
const fruit = new Fruits();
fruit.name = name;
fruit.price = await this.setPrice();
return fruit;
}
private static async setPrice(){
return setTimeout( () => { Math.floor(Math.random() * 100 ) }, 3000); // 時間がかかる処理;
}
}
const main = async() => {
const apple:Fruits = await Fruits.build( 'apple');
console.log( apple.price );
}
main(); // e.g. 17879
参考
必要な1次ソースがすぐ見つけられなかったので、勝手ながら下記ブログを参考にさせていただきました。分かりやすかったです。
- 【JavaScript】async constructor がしたい - ゆっくりのんびり。 https://puyobyee18.hatenablog.com/entry/2020/07/03/155002
- How to Write an Async Class Constructor in TypeScript or JavaScript | by Gabe Szczepanek | Better Programming https://betterprogramming.pub/how-to-write-an-async-class-constructor-in-typescript-javascript-7d7e8325c35e
Discussion