typescriptで非同期処理するよ
Q&A
Closed
個人備忘録です。
エラー起きたらすみません。
MDNのJavascript非同期処理のサンプルコード読んでも「で?」となる人向け。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
読者対象:
非同期処理がそもそもイメージつかない
匿名関数ってなんだろう?
Promiseとawait/asyncの違いがわかんない
非同期処理とは?
きちんとした概念は下記サイトなど参考にしてください。
https://buildersbox.corp-sansan.com/entry/2020/02/12/110000
通常プログラムは上から実行されますが、非同期処理でコードを書くことで一斉に処理が走ります。
例えばユーザがページを読み込んだ際に、
そのページのリクエストが全て動作し情報をとってきてくれます。
順番にとってきてたらユーザはイライラしてたまらないですね〜
同期処理
下記は通常の同期処理です。
呼び出した順に実行されます。
class Main {
hogeA() {
console.log('hogeA')
}
hogeB() {
console.log('hogeB')
}
}
では次に非同期処理にいきましょう。
非同期処理
サンプルのソースです。
これからの説明は下記の記述を元にします。
class Main {
HogeA() {
return new Promise((resolve:Function, rejects:Function) => {
this.sleep(1000, () => {
console.log("hogeA")
resolve("hogeA成功")
})
})
}
HogeB() {
return new Promise((resolve:Function, rejects:Function) => {
this.sleep(100, () => {
console.log("hogeB")
resolve("hogeB成功")
})
})
}
sleep(time: number, func: Function) {
setTimeout(func, time);
}
}
const main = new Main()
main.HogeA()
main.HogeB()
// 実行結果
// hogeB
// hogeA
実行した順番ではなくなりました。
急に難易度が上がった気がします。
一つずつ説明します。
sleep(time: number, func: Function) {
setTimeout(func, time);
}
setTimeOut()を使用しています。
今回はHogeA,HogeBの処理にかかる時間を設定するために使用しています。
引数として処理にかかる時間time
、実際の処理内容func
を渡しています。
余談ですが、func
には関数が入りますので、引数で渡さない場合は下記のように匿名関数で記述しましょう。
class Main {
HogeA() {
return new Promise((resolve:Function, rejects:Function) => {
this.sleep(100)
})
}
~~~省略~~~~
sleep(time: any){
setTimeout(() => {
console.log("konnakanji") // 上記でfuncとして渡している関数の処理がここに当たる
}, time)
}
}
const test = new Test()
test.sleep(100)
// 実行結果
// konnakanji
次に実際の非同期処理の内容を説明します。
Promiseは処理が実行中の処理を監視し、処理が問題なく完了すればresolve、
反対に問題があればrejectを呼び出してメッセージを表示します(参考:https://techplay.jp/column/581)
Promiseも関数、resolveもrejectも関数です。
resolveはPromiseが成功した場合、rejectsは失敗した場合の処理を渡すことができます。
HogeA() {
return new Promise((resolve:Function, rejects:Function) => {
this.sleep(1000, () => {
console.log("hogeA")
resolve("hogeA成功")
})
})
}
さらに分解すると下記のようになります。
Promiseには匿名関数を格納したfuncを渡すことで上と同じ処理を行うことができます。
ややこしくなってきた。
HogeA() {
const func = (resolve: Function, rejects: Function) => {
this.sleep(1000, () => {
console.log("hogeA")
resolve("hogeA成功")
})
}
return new Promise( func )
}
また、全ての非同期処理が完了したのか確認したい場合はPromiseのall()で取得することができます。
Promise.all([ main.hogeA(), main.hogeB() ]).then(()=> {
console.log("完了したよ")
})
// 完了したよ
// [ "hogeA", "hogeB" ]
ただ、こちら各処理にresolveでPromiseでかいた処理が成功したことを明記していないと
[ "hogeA", "hogeB" ]
は取得できないので注意。
おまけ
async/await は Promise を同期的なコードのように書けるとのことです。
参考:https://qiita.com/suin/items/97041d3e0691c12f4974
async HogeA() {
await this.sleep(1000, ()=> {
console.log("awaitしてるよ")
})
console.log("awaitの処理終わったよ"
}
// awaitしてるよ
// awaitの処理終わったよ