🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Leaflet

Leafletは、Web上で地図を作成するためのJavaScriptライブラリ。人気のあるJavaScript地図ライブラリのうちの一つでオープンソースです。軽量でインタラクティブな地図を手軽に表示することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

解決済

2回答

711閲覧

$.when().の後のdone(function(){})の処理をしてくれない

pegy

総合スコア245

Leaflet

Leafletは、Web上で地図を作成するためのJavaScriptライブラリ。人気のあるJavaScript地図ライブラリのうちの一つでオープンソースです。軽量でインタラクティブな地図を手軽に表示することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

1クリップ

投稿2019/11/08 12:24

編集2019/11/08 15:36

Leaflet.jsというMap操作関連のライブラリを使いながら非同期で現在地を取得してユーザーのviewを移動する(flyTo method)コードを以下の通り記載しているのですが、done()部分がwhenの後に実行されません。
もし原因がわかる方がいらっしゃればアドバイスをいただけると幸いです。
よろしくお願いいたします。

html

1<style>.errDisplay{display:none;}</style> 2<div class="errorBox errDisplay">error</div>

javascript

1var $defer = new $.Deferred(); 2var opts ={ 3 enableHighAccuracy: true, 4 timeout: 5000, 5 maximumAge: 0 6} 7 8/*move current*/ 9$('.current').on('click',function(){ 10 $.when( 11 $defer, 12 $('.errorBox').removeClass('errDisplay'), 13 navigator.geolocation.getCurrentPosition(cpSuccess,cpFail,opts) 14 ).done(function(){ 15 setTimeout(function(){ 16 alert("here");//ここが処理されません 17 return $defer.resolve(); 18 },1000) 19 return $defer.promise(); 20 }) 21}) 22 23/*current position*/ 24function cpSuccess(position){ 25 const currentLat = position.coords.latitude; 26 const currentLng = position.coords.longitude; 27 28 map.flyTo([currentLat,currentLng],14); 29 30 if (current_marker) { 31 map.removeLayer(current_marker); 32 } 33}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

括弧の対応がとれていないため、構文エラーでそもそも実行されていないと思います。コンソールにエラーが出力されていませんか? それともコードの後半を掲載しなかっただけでしょうか。

また、$when の引数に渡されている $defer が、$defer が解決されるまで解決されないようになっているため、 .done() に渡されたコールバックが実行されることはありません。

ご提示のコードは色々とおかしなコードになってしまっていますので、まずは非同期処理の基本から順を追って理解していくといいと思います。

javascript

1var $defer = new jQuery.Deferred() 2$.when($defer).done(function() { 3 //下に記載されている $defer.resolve() が実行された後に実行される。 4 alert('その後に実行') 5}) 6setTimeout(function() { 7 // 1秒後にここが実行される 8 alert('1秒経過') 9 $defer.resolve() 10}, 1000)

このように、 when() に渡したオブジェクトがすべて解決されると、 when に渡したコールバック関数が実行されます。 when() に渡すコールバック関数の中に遅延されたオブジェクトの解決処理を入れてしまうと、その処理は永久に実行されません。

逆に、 Deferred や Promise のような、将来解決されることを意図していないオブジェクトを when の引数に与える意味はありません。($('.errorBox').removeClass('errDisplay') など)

投稿2019/11/08 14:44

R.Mizukami

総合スコア1086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2019/11/08 16:18 編集

コメントいただきありがとうございます。ざっくりと順番を考えた場合 1) whenの引数の$deferが解決される 2) doneに渡したコールバック関数が実行される したがって、私が記載したコードはdone()の中に$defer.resolve()としてしまっているため、whenが解決されることがなくdoneのコールバック関数が実行されることがないと理解することができました。また意図した動作を実現することができました。 一方、以下の2点だけ理解できない点があり、これを今調べているのですが、一旦コメントバックさせていただきます。 ・$defer.resolve()としてdeferオブジェクトのresolveメソッドで解決するのとreturn $defer.resolve()でオブジェクトを返してもどちらでも解決して処理がdoneに移るのですが ・promiseについて混乱してきました。。。deferオブジェクトにpromiseメドッドがあったりpromiseオブジェクトにresolveメソッドがあったりそれぞれの役割がどうしても抽象的でわからないので、これは以下のような記事を見ながら奮闘中です、、、難しい https://app.codegrid.net/entry/deferred-1 気づきをたくさん与えてくださり、本当にありがとうございます
pegy

2019/11/08 16:38

いえ、申し訳ございません、私の勘違いが一つございました。解決したと思ったのですが、結果的に1秒待ってdoneの処理がされているだけで本来意図している、whenのなかの処理、つまり 「現在位置を取得してflyToメソッドで視点を移し終えたら」次に「removeClassする」ではなく 「1秒経過したら」次に「removeClassする」となっておりました。
guest

0

ベストアンサー

ざっと見ただけですし、実際に走らせてもいないので間違っているかもしれませんが。

$.when( の次の行の $defer, が原因ではないでしょうか。
これがあるために $.when が終了せず、done が実行されないのだと思います。
この行の意図を確認し、不要なら消してみてください。

投稿2019/11/08 14:41

2KOH

総合スコア999

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2019/11/08 16:18

仰る方法で確かに実装することができました、今原因を考え中です、、 お力添えありがとうございます。
pegy

2019/11/08 16:39

上記のコメントと同様ですが解決したと思ったのですが 「現在位置を取得してflyToメソッドで視点を移し終えたら」次に「removeClassする」ではなく 「1秒経過したら」次に「removeClassする」となっており 解決がしておりませんでした。。申し訳ございません。
2KOH

2019/11/09 03:27

このコメントでは、何を実現したくて、何を試し、どんな問題が発生しているのか、わかりません。 未だ「done()部分がwhenの後に実行されない」という問題点が解消されていないのか、解消されたが別の問題が発生したのかも読み取れません。 現在の状況をわかりやすく書き直してください。
pegy

2019/11/09 07:57

コメントありがとうございます、失礼いたしました。 ●実現したいこと 1.currntをクリックする 2..errorBoxからerrDisplayが.removeClassされる 3.whenのなかでnavigator.geolocation.getCurrentPosition(cpSuccess,cpFail,opts)関数が実行される、具体的にはgeolocationで位置情報が取得されてleafletライブラリのflyToメソっドで現在の視点が現在地に移る 4.3.の処理が終わるとerrorBoxにerrDisplayがaddClassされる もっとも重要なことは3の処理が終わった後に4が実行されてほしいということになります。 ●お二方のご回答から修正したコード $('.current').on('click',function(){ $('.errorBox').removeClass('errDisplay') if (navigator.geolocation) { $('.loading').removeClass('loading_hide') $.when( $defer ).done(function(){ $('.errorBox').addClass('errDisplay') }) setTimeout(function(){ navigator.geolocation.getCurrentPosition(cpSuccess,cpFail,opts) $defer.resolve(); },1000) }else{ alert("位置情報の取得に失敗しましたerr:[1]") } }) ●発生している問題 もともとの問題であったremoveClassとaddClassが同時に処理されてしまう点は解消したのですが、このコードによってremoveClassされてから1秒後にはaddClassが実行されてしまう、つまり上記でいう3の処理はまだ終わっていないにもかかわらず4が実行されているということが現在の問題です。3の処理はgeolocationを利用しているので現在地を取得する時間は1秒のこともあれば5秒のこともあり予測することができないため、3の処理が終わればという条件で4を実行したいのですがそれが実装できないという点にございます。 何かあればまたご指摘をいただければ幸いです。 よろしくお願い申し上げます。
2KOH

2019/11/09 09:27

根本的な問題として、非同期処理が理解できていないようで、やりたいことと実際のコードが大幅に乖離しているようです。 ブレークポイントを設定したり、コードに console.log を追加するなどで、コードがどういう順番で実行されているか確認してみてください。 3の処理が終わった後に4が実行されていないとかそういうレベルではなく、メチャクチャな順番で実行されてしまっていることがわかると思います。 これを修正することは回答の範疇を超えます。 非同期処理(navigator.geolocation.getCurrentPosition ではコールバックが使われているので、必要ならコールバックも)をきちんと理解し、その上で自分で修正してみて、それでもわからなければそのときに質問し直してください。
pegy

2019/11/09 12:42

コメントありがとうございます。承知をいたしました、地道に確認をしてみようと思います。 よろしくお願い申し上げます、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問