はくなまたた

大丈夫、問題ない、どうにかなるさ

javascriptの非同期について

javascriptを勉強していると何点がつまずく点があったが、そのひとつが非同期通信だった。

関数で返り値を取ろうとしても処理のタイミングによっては値が取れないことがあります。

下の例だと戻り値を2倍しているだけなのですが、わざとsetTimeoutで処理のタイミングをずらしています。こうなるとfunc1の値が返ってくる前にfunc2を実行してしまってundefinedになるので注意が必要です。ここらへんはjavascriptを触るとみんな陥るところかもしれない。

これを解決するためにcallbackを勉強して次にpromiseを勉強して次にasync/awaitを勉強することになると思うがひとつずつ理解していかないと後々やっかいだと気付いた。

  let ret = func1(2);
  ret = func2(ret);
  func3(ret);

  function func1(d) {
    setTimeout(function() {
      console.log('1:' + d);
      return d * 2;
    }, Math.random() * 1000);
  }
  function func2(d) {
    setTimeout(function() {
      console.log('2:' + d);
      return d * 2;
    }, Math.random() * 1000);
  }
  function func3(d) {
    setTimeout(function() {
      console.log('3:' + d);
    }, Math.random() * 1000);
  }   
 

解説はほかのサイトで丁寧に書かれているのでそちらを参考にしてください。

とりあえずcallback関数を使えば関数そのものを引数に渡すことができるので、関数の数珠繋ぎみたいなのが出来ます。

これを利用するとfunc1の結果をfunc2に渡してfunc3に渡すみたいな数珠繋ぎが完成します。

下記を実行すると上から順番に実行されます。

  func1(2func2);

  function func1(dcallback) {
    setTimeout(function() {
      console.log('1:' + d);
      callback(dfunc3);
    }, Math.random() * 1000);
  }
  function func2(dcallback) {
    setTimeout(function() {
      console.log('2:' + d * 2);
      callback(d * 2);
    }, Math.random() * 1000);
  }
  function func3(d) {
    setTimeout(function() {
      console.log('3:' + d * 2);
    }, Math.random() * 1000);
  }
 

簡単そうですが、見慣れない書き方なので最初パッと見ただけで理解できませんでした。あとアロー関数も変に省略されていてパッと見意味がわかりませんでした。

Javascriptって色んな事が出来て色んな書き方が出来てしまうので、慣れるのに時間がかかるなと思いました。ネットにサンプルは色々落ちているが人によって書き方が違うのでそういった点もJavascriptを最初に触って戸惑う点かもしれません。