DEV Community

kaede
kaede

Posted on

TypeScript 基礎 -- Promise を返す関数を作り、Promise が解決された後に動く処理を書く

環境構築

npm --version
8.6.0
Enter fullscreen mode Exit fullscreen mode

typescript をいれるための npm のインストール
9 で苦戦したのでそれ未満にした。

npm i typescript -g
Enter fullscreen mode Exit fullscreen mode

tsc コマンドのための typescript のインストール

node --version
v18.0.0
Enter fullscreen mode Exit fullscreen mode

tsc とその後の為の node

これらを入れておく。

npm i -g ts-node 

added 19 packages, and audited 20 packages in 910ms

found 0 vulnerabilities
Reshimming asdf nodejs...
Enter fullscreen mode Exit fullscreen mode

さらにコンパイルと実行を続けてやるために、ts-node も入れる。

これで準備完了。

なお、ts-node は ファイル名に .ts をつけないと .js の方を読み込むので注意。


Promise とは?

https://typescriptbook.jp/reference/promise-async-await#promise%E3%81%A8%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9

連続するもの。処理Aが終わってから処理B、処理Bが終わってから処理C...と終わるのを待って実行することができる。


実行時の注意点

https://stackoverflow.com/questions/27573365/how-to-use-typescript-with-native-es6-promises

package.json に書いてある target が es2015 未満になっていると tsc では実行できない。

promise.ts:2:14 - error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later.

2   return new Promise((resolve) => {
               ~~~~~~~
Found 1 error.
Enter fullscreen mode Exit fullscreen mode

Promise で返ってくる関数を呼び出してみる

function request1(): Promise<number> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(1);
      console.log("resolved")
    }, 1000);
  });
}
console.log(request1());
console.log("not promise")
Enter fullscreen mode Exit fullscreen mode

Promise のインスタンスを作り
内部で何が終わったら解決するか定義する。
この場合は setTimeout で 1 秒たったら解決し
console.log で resolved と print するようにした。

これを実行すると

ts-node promise.ts
Promise { <pending> }
not promise
resolved
Enter fullscreen mode Exit fullscreen mode

関数の返り値がまだないので 処理待ちの Promise だと表示され
並列実行なので、Promise が返ってくる前に関数外の not promise と表示させる処理が先に動き
Promise が解決された後、resloved が print される。


Promise 解決後に .then( (_) => {} で処理を動かすようにする

console.log("not promise")
request1().then((_) => {
  console.log("after promise resolved");
})
Enter fullscreen mode Exit fullscreen mode

先程の Promise が返ってくる処理では
.then と (_) をつけることで、
Promise が終わった後に動く処理を付け足すことができる。

ts-node promise.ts
not promise
resolved
after promise resolved
Enter fullscreen mode Exit fullscreen mode

async で関数を定義することで、返り値を暗黙的に Promise にする

async で定義すると、返り値 Promise でラップされる。

async function asyncPromiseFunc(): Promise<number> {
  return 1;
}
asyncPromiseFunc().then((_) => {
  console.log("after promise resolved");
})

console.log("not promise")
Enter fullscreen mode Exit fullscreen mode

setTimeout しなくても非同期の方が通常処理より遅くなるので、setTimeout は省略した。
これを実行すると

ts-node promise.ts
not promise
after promise resolved
Enter fullscreen mode Exit fullscreen mode

ちゃんと not promise の出力の後に async での関数の後に then が動いて after promise resolved が実行されるので

Proimse が返ってきていることがわかった。


まとめ

関数の返り値を new Promise で返すと、非同期で並列スレッドで動き、他の処理を先に動かすことができる。

promiseFuncName.then( (_) => { } を使うと、
関数の返り値が帰ってきた後に {} 内部の処理を動かせる。

関数に async をつければ、返り値を new Promise() で囲わなくても、暗黙的に Promise として返るようになる。


次回やること

Promise の返り値を扱う
( then で引数を使う、await で受け取る )

Top comments (0)