4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

非同期処理を含む処理順のこと(そしてたまにPromise.allのこと)

Last updated at Posted at 2024-01-11

TD;LR;

プログラムは基本的に同期的に処理を書く
非同期処理は速度的に必要な場合に検討する
そのときにPromise.allのことを思いだすといいかもしれない

非同期実行は常に罠

現代のJavascriptでは非同期処理が多用されます
build inな関数でもfetchとかcreateImageBitmapなどのように非同期のものもある時代です
LINEのSDKのloginもPromiseかえしますし、json取得して、そのファイルの中身を読んで画像を取得してとかの処理もある時代です
こういったときに実行順序が必要なのか(前の処理に依存するのか、後の処理に必要なのか)、不定でよいのか(他の処理に影響されないのか)を判断できてないと問題を引きおこします
処理はできるだけ同期的に書く方がよく、非同期処理は実行時間的に断然有利な場合に検討するものだとは思います(数10msでは可読性を重視してよいくらい)

非同期処理と同期処理、きちんと理解していますか?

JavascriptにおいてPromiseまわりを理解するのは少し難易度が高いのは理解できます。しかしこれを理解しないと「たまたま動く」コードを書くことしかできませんし、それではプログラムが書けるとは言えないでしょう
自信をもってJavascript ProgrammingするためにもPromiseやそれに付随するawait/asyncのことをしっかり理解しおいてほしいところです
今回は依存関係のあるときのコードについて簡単に書いておきます

例題

A, B, C, Dの処理があるとします

A,B,C,Dがすべて同期的な処理(Promiseではない)

const A = () => {}
const B = () => {}
const C = () => {}
const D = () => {}
const main = () => {
    A();
    B();
    C();
    D();
}

こういうことです

A,B,C,Dがすべて非同期的な処理であるがA→B→C→Dの順番に処理しなけえればいけない場合

await/async使いましょう

const A = aync() => { return a}
const B = aync(arg) => { return arg + b}
const C = aync(arg) => { return arg + c}
const D = aync(arg) => { return arg + d}
const main = aync() => {
    const resultA = await A();
    const resultB = await B(resultA);
    const resultC = await C(resultB);
    const resultD = await D(resultC);
}

せやな。全部awaitすればいいのだ
もしここでA()の呼びだしのawaitをはずすとBは引数にPromiseがわたされてしまう惨事を引きおこします
非同期なのでAの結果がでる前にBを実行します。つまり死にます

A,B,C,Dが非同期処理でA,B,Cの実行順は問わないが、すべて終わったあとでDを呼ぶ.(A,B,C)→Dの場合

この例は上のように全部同期的にして実行してしまってもよいのですがPromise.allとか知ってるとだいぶオシャレになります

const A = aync(arg) => { return arg + a}
const B = aync(arg) => { return arg + b}
const C = aync(arg) => { return arg + c}
const D = aync(a,b,c) => { return a + b + c}
const main = aync() => {
    const arg = 42;
    const pA = A(arg);
    const pB = B(arg);
    const pC = C(arg);
    Promise.all([pA, pB, pC]).then((values) => {
        D(values[0], values[1], values[2])
    }) 
}

loginしてる最中に画像落としたりとか画像変換したりとかのときにはPromise.allさんを思いだしてあげるとよいかもしれません

まとめ

  • 同期的か非同期的かを判断しましょう
  • 実行順序が前の処理に依存するか、あとの処理が依存しているかを明確にしましょう
  • できる限り同期的に記述しましょう(性能問題がない限りにおいて)
  • 非同期処理を綺麗にまとめるときにPromise.allのことを思いだしてあげてください(フラグ処理とか書かないようにね)

おまけ

実際のところわたしはJavascript好きじゃないし、理解できてないんだがな(V8のコードとか理解してないし)

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?