@noricoonco

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

typescriptで非同期処理するよ

個人備忘録です。
エラー起きたらすみません。

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の処理終わったよ
0 likes

1Answer

Your answer might help someone💌