質問: MONACAでアプリ開発をしております、初歩的な質問で申し訳ないのですがご教授頂けませんでしょうか、よろしくお願いします。 ng-clickで引数を2つ指定しました。 1.画面遷移の関数 2.DBからlazy-repeatに出力する関数 この場合に処理の遅い端末で確認したところ画面遷移が先に実行されてしまい、lazy-repeatでのリストが表示されません、timeoutを使い1の画面遷移の処理を遅らせることで表示事態の問題は解決したのですが、1の処理を遅らせるのではなく2の処理完了後に1の関数を実行するにはどうしたら良いのでしょうか?ご教授お願いします。
回答: 今回の問題はデータ取得が非同期のため発生します。 プロミスを使うと、非同期を同期のように処理することができます。 データ取得処理で、成功:`resolve`、失敗:`reject`を呼び出すと、`then(成功コールバック,失敗コールバック)`の各コールバックを実行します。 今回の場合、`resolve`で取得したデータを渡し、成功コールバックで受け取り、画面遷移に必要な処理を書けばうまく動作すると思います。 以前はデータ取得処理で`$scope.$emit`でデータを渡し、`$scope.$on`で受け取る方法を多用していましたが、あまりにも複雑な処理となるため、上記方法に落ち着きました。 ``` // ng-clickで呼び出す関数 $scope.button1 = function() { getData().then(function(list) { // 取得成功 $scope.list = list; // 取得後の処理を以下に書く : : : }, function(err) { // 取得失敗 console.log(err.code); console.log(err.message); }); }; // 例としてデータベース:testdb、テーブル:t_dataが存在すると仮定 function getData() { var def = $q.defer(); var list = []; var sql = null; var db = window.openDatabase("testdb", "", "testdb", 1024 * 1024); db.readTransaction(function(t) { sql = "SELECT id, name"; sql += " FROM t_data"; sql += " ORDER BY id"; t.executeSql(sql, [], function(t, r) { for (var i = 0; i < r.rows.length; i++) { list.push({ id: r.rows.item(i).id, name: r.rows.item(i).name }); } }, function(t, err) { // 失敗 def.reject(err); }); }, function(err) { // 失敗 def.reject(err); }, function() { // トランザクション終了でlistを返す def.resolve(list); }); return def.promise; }; ```