JavaScriptの処理ロジック(ロジックの構築)に
お知恵をお借りしたいと思います。
【実現したいこと】
コード内の①と②に ①⇒②の処理順を設定したい。
ただし、①は実行されるとは限らない。
②は必ず実行されるが、①よりも後に実行され、
①で値がセットされていれば、①の値を使って②を処理したい。
【困っていること】
②は必ず起動しなければいけません。
現状、このコードを実行すると、②⇒①の順で実行されてしまうため、
①⇒②となるように、何らかのロジックを入れて制御したいです。
上記で記載したように ① が実行されるかわからないため、
なんらかの形で②の起動条件を決めないといけないかな、と思っています。
【コードの説明】
これはスマホアプリの挙動を制御するプログラムです。
ons.ready(function() {});
アプリが起動したら必ず実行される内容を記述する部分と思ってください。
(アイコンから起動した場合でも、プッシュ通知から起動した場合でも)
②init(mode)
アプリが起動したら実行される処理が記載されていると思ってください。
(アイコンから起動した場合でも、プッシュ通知から起動した場合でも)
①window.FirebasePlugin.onNotificationOpen
アプリが「プッシュ通知」から開かれた場合のみ実行される部分です。
そのため「アイコン」から起動された場合は実行されません。
【追記ここから】
なお、①のwindow.FirebasePlugin は Cordova という
アプリ開発環境が前提です(だと思っている)ので
ons.ready の中に置く必要があります。
※外に関数で定義して、ons.readyの中から外の関数を呼ぶでもOKです。
②のinit()は ons.readyの外にあっても処理自体は動きますが、
どこかで呼び出し、①⇒②の順でなければなりません・・・。
【追記ここまで】
<script> ons.ready(function() { var mode = "icon"; //① プッシュ通知から開かれた場合のみ実行される window.FirebasePlugin.onNotificationOpen(function(notification){ mode = "push"; ・・・・ }); //②...初期化処理initをmodeを引数にして起動 init(mode); });// ons.ready()ここまで </script>
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
ベストアンサー
なるほど、なんとなく分かりました。
確かに難問ですね。
というのも、この部分が非同期実行されることにあります。
JavaScript
1// ① プッシュ通知から開かれた場合のみ実行される 2window.FirebasePlugin.onNotificationOpen(function(notification){ 3 mode = "push"; 4 // ・・・・ 5});
JavaScriptに於けるonXXX
というメソッドは、
「もし○○の条件を満たしたら渡した関数実行してね、じゃ俺は下の行を実行するから〜」
…という作りになっています。
JavaScriptはシングルスレッドで動作するので、
ネットワークやファイルI/Oの操作を待っているとその度にプログラムがプチフリしまくる事になります。
その対策として、非同期処理は待たずにさっさと次の行を実行する設計を選択しています。
質問文との相性が悪い原因は、
1が行われるか行われないか全くわからない状況で2の処理を待つか実行するかを選択しなければならない
…という究極の二択を迫られている事にあります。
- 一生Push通知クリック判定を待ち続けて初期化処理が行われない
- Push通知クリック判定を無視してさっさと初期化処理を継続するか
これはどうしようもない問題なので、設計を変えましょう。
Push通知の目的ってそもそもなんですか?
例えばTwitterのアプリだったりした場合、
友達のリプライやリツイートのPush通知をタップします。
そのタップしたリプライやリツイートのページを開きたいのではないでしょうか?
なので、Push通知タップからのinitメソッドを実行することは諦めて、
Push通知タップはあくまでその画面へ遷移する為のトリガーにしましょう。
投稿2017/11/13 05:51
総合スコア21158
0
kei344 さんのコメント欄のアドバイスで解決可能と考えていたので、この展開は意外でした。
同期処理
ただし、①は実行されるとは限らない。
②は必ず実行されるが、①よりも後に実行され、
①で値がセットされていれば、①の値を使って②を処理したい。
同期処理でこの課題を解決するのは簡単です。
JavaScript
1'use strict'; 2var foo = { 3 a: 0, 4 process1: function process1 () { 5 this.a = 1; 6 console.log('①'); 7 }, 8 process2: function process2 () { 9 console.log('②', this.a); 10 } 11} 12 13var bar = 1; 14 15if (bar) { 16 foo.process1(); 17} 18foo.process2();
しかしながら、ons.ready
, window.FirebasePlugin.onNotificationOpen
はイベント駆動なので、使用しているライブラリ/DOMの「イベントモデル」のルール内で対応するハンドラ関数が発火します。
イベントモデル
kei344 さんが紹介して下さったURLからリンクを辿ると、イベントの発火順に触れた記事が見つかります。
Google先生に尋ねれば、pluginが利用可能になるタイミングが deviceready イベントである事が分かるので、次のように書きます。
JavaScript
1document.addEventListener("deviceready", function handleDeviceReady (event) { 2 console.log(event.type); // "deviceready" 3 4 window.FirebasePlugin.onNotificationOpen(function(notification){ 5 console.log('notificationOpen'); 6 }); 7}, false); 8 9ons.ready(function() { 10 console.log('ons.ready: Onsen UI load complete'); 11});
このコードで「deviceready -> ons.ready」の順番で発火する事は保証されているので、「onNotificationOpen と ons.ready のどちらが先に発火するイベントモデルなのか」が問題ですが、検証すればすぐに結果は出るでしょう。
(考えづらいと思いますが、もし、ons.ready
が先に発火するのであれば、onNotificationOpen が発火するまで数秒間待機させるか、別のイベントを探す必要があります。)
NotificationOpen イベント
- App is in foreground:
i. User receives the notification data in the JavaScript callback without any notification on the device itself (this is the normal behaviour of push notifications, it is up to you, the developer, to notify the user)
2. App is in background:
i. User receives the notification message in its device notification bar
ii. User taps the notification and the app opens
iii. User receives the notification data in the JavaScript callback
NotificationOpen イベントはバックグラウンド実行されたアプリから復帰した時にも発火するイベントです。
従って、先のコードで処理を行うと既に初期化処理が終わっているアプリに対して、バックグラウンドから復帰時にもう一度初期化処理が走る事になります。
それが望まない動作であるなら、フラグ管理する等して初期化済かどうかを判断する条件分岐処理が必要になります。
ちなみに、Monaca には resume
イベントが用意されているようです。
Re: Clavat さん
投稿2017/11/13 08:16
編集2017/11/13 08:54総合スコア18162
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/13 09:42
0
Onsen UI はよくわかりませんが、window.FirebasePlugin
が ons
のコード内で定義されていないなら、下記のような方法で出来ると思います。
JavaScript
1 var mode = "icon"; 2 //① プッシュ通知から開かれた場合のみ実行される 3 window.FirebasePlugin.onNotificationOpen(function(notification){ 4 mode = "push"; 5 ・・・・ 6 }); 7 ons.ready(function() { 8 //②...初期化処理initをmodeを引数にして起動 9 init(mode); 10 });// ons.ready()ここまで
投稿2017/11/13 03:14
総合スコア69400
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/13 03:45
2017/11/13 03:48
2017/11/13 03:54
2017/11/13 03:58
2017/11/13 03:59
2017/11/13 05:02
2017/11/13 05:14
2017/11/13 05:56
0
おそらくkei344さんが正しい解説をつけてくれているようなので
ロジックの話だけ
コード内の①と②に ①⇒②の処理順を設定したい。
ただし、①は実行されるとは限らない。
②は必ず実行されるが、①よりも後に実行され、
①で値がセットされていれば、①の値を使って②を処理したい。
論理的に矛盾しているように見受けられます
「②は必ず実行されるが、①よりも後に実行される」ということは
②は①に依存しているということです。
さらに「①は実行されるとは限らない」わけですから
それに付随して「②は実行されるとは限らない」状態です
その状態で「②は必ず実行される」となっているので、条件があいません。
流れとしては
- ①が実行されたら②は実行される
は確定だとして
- ①が実行されなかったら②は実行されない
- ①が実行されない場合でも②は実行されるが他のなにかトリガーが定義されている
のどちらかを定義する必要があります
投稿2017/11/13 04:42
総合スコア114784
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/13 04:54
2017/11/13 05:03
2017/11/13 05:20
0
プラグインを知らない、回答を全て読んでいませんが…
promiseを使って、非同期処理にすればよいのではないでしょうか?
投稿2017/11/14 00:23
総合スコア17
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/13 06:31 編集
2017/11/13 06:49 編集
2017/11/13 06:49
2017/11/13 07:13