ニフクラmBaaSお役立ちブログ

スマホアプリ開発にニフクラmBaaS。アプリ開発に役立つ情報をおとどけ!

JavaScript(スクリプト機能)における非同期処理のループ実装の注意点

https://cdn-ak.f.st-hatena.com/images/fotolife/m/mbaasdevrel/20171212/20171212211252.png

mBaaSではJavaScript SDKを提供していますが、これはMonacaやWebアプリケーションに限らず、スクリプト機能を使う際にも用います。普段SwiftやJava、Objective-C、Unityなどを使っている方にとって、JavaScript/Node.jsを使った開発は慣れないものでしょう。

JavaScriptと他のプログラミング言語の大きな違いの一つに非同期処理があるかと思います。かつてはコールバック、現在はPromiseによって非同期処理を意識したプログラミングを行う必要があります。

そうした実装を行う中で、特に注意して欲しいのがデータを一括処理(保存や更新、削除など)を行う場合です。非同期処理では現在のネットワーアクセスが完了する前に次のアクセスを開始してしまったり、全体の処理を終了してしまう可能性があります。例えば以下のような書き方はよくありません。一気に大量のネットワークアクセスが発生するでしょう。

良くない書き方

// ary が処理対象の配列
for (let i = 0; i < ary.length; i += 1) {
  const item = new Item(ary[i]);
  item
    .save()
    .then((obj) => {
      
    })
    .catch((err) => {
      
    });
}

正しい書き方

考え方としては、一つ前の処理が終わった後で、次の処理を実行する必要があります。つまり保存処理の中でもう一度保存処理を呼び出す(循環参照)必要があります。

// ary が処理対象の配列
const save = (index) => {
  // 処理対象を抽出
  const item = new Item(ary[i]);
  // 保存処理(後述)
  // 終わったら次のデータに移る
  save(index + 1);
};
save(0); // 最初の呼び出し

データストアの保存処理との組み合わせ

保存処理自体はループ処理の時と変わりません。

// ary が処理対象の配列
const save = (index) => {
  // 処理対象を抽出
  const item = new Item(ary[i]);
  // 保存処理(後述)
  item
    .save()
    .then((obj) => {
      // 終わったら次のデータに移る
      save(index + 1);
    })
    .catch((err) => {
      console.error('エラーです');
    });
};
save(0); // 最初の呼び出し

このように循環参照することでデータを順番に処理しながら進められるようになります。ネットワークが非同期でないプログラミング言語に比べるとループ処理が分かりづらいのですが、押さえておくとmBaaSのスクリプトが作りやすくなるかと思います。

ドキュメント : 開発者向けドキュメント | ニフクラ mobile backend

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。