質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Chrome extension

Chrome拡張機能

Q&A

解決済

2回答

744閲覧

Javascript イベントリスナの引数のcallbackに監視している変数を渡したい

navca

総合スコア44

JavaScript

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

Chrome extension

Chrome拡張機能

0グッド

2クリップ

投稿2019/08/03 09:50

chrome拡張を作っています。chrome拡張に固有の問題ではないので題名にはChrome拡張とは書いていません。

やりたいこと
onMessage.addListenerでメッセージを受けて、第三引数のcallbackで返信したいのですが、返信したい変数がObject.definePropertyで監視している変数で、onMessage.addListenerとObject.definePropertyはどちらが先に実行されるか保証されていないため、addListenerのcallback内にdefinePropertyをじかに書いてしまうわけにいかず、こまっています。

chrome.runtime.onMessage.addListener((msg, sender, callback) => { if(msg.hoge){ callback(ids.foo) } })
Object.defineProperty(ids, 'datas', { get : () => this.datas, set : newValue => { let name = Object.keys(newValue)[0] this.datas[name] = newValue[name] let g = this.datas; if([g.foo,g.bar,g.fizz].every(x => !x)){ chrome.runtime.sendMessage(g.for, {'id':g.bar}) this.datas = {} } } })

やったこと
Promise.allが使えるかと思いましたが、undefinedになてしまいます。

setTimeout(() => {//chrome.runtime.onMessage.addListenerの代わり function p_wrapper(){ return new Promise(r => { r({'foo':'bar'}) }) } }, 5000) function p_wrapper2(){ return new Promise(r => { //Object.defineProperty(ids~~~ r('hoge') }) } Promise.all([p_wrapper, p_wrapper2]).then(msg => {console.log(msg)}) // p_wrapper is not defined

Object.definePropertyも広く言えばイベントリスナのようなものだと思いますが、イベントリスナを入れ子にする必要のある場合どう対処したらよいでしょうか?
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

自己解決

https://developer.chrome.com/extensions/runtime#event-onMessage
上記の「同じドキュメントに複数のonMessageリスナーがある場合、応答を送信できるのは1つだけです。」について、
同一ドキュメント内に

chrome.runtime.onMessage.addListener(request, () => {if(request.foo)}) chrome.runtime.onMessage.addListener(request, () => {if(request.bar)})

のように、違うメッセージを受信する形にしていてもcallbackが送信されるのは一つだけという風に勘違いしていたため、chrome.runtime.onMessage.addListenerをもう一つ書けば良い所を、ドキュメント内唯一のonMessage.addListenerのcallback内には書けないという質問の趣旨でしたが、上記のコードOKでしたので、promise.allにて解決しました。

投稿2019/08/19 12:32

navca

総合スコア44

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

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

0

いまいちやりたいことがわかっていない可能性が有りますが、グローバル変数でも作って受け渡せばよいのでは。
(ページと拡張で変数の共有できるような仕組みとか多分あると想定してます。無くてもonMessageのたびにdefinePropertyを仕掛けたページを読みに行く処理をして、当該変数を拾えそうな気がします)

JS

1let XXX = ''; 2chrome.runtime.onMessage.addListener((msg, sender, callback) => { 3 if ( XXX ) {} 4}) 5Object.defineProperty(ids, 'datas', { 6 set : newValue => { 7 XXX = 'O'; 8 } 9}); 10 11ids.datas = ''; // こうしておけば1回は動くはずなので初期化処理でもすればよいのでは。

投稿2019/08/08 18:12

kei344

総合スコア69407

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

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

navca

2019/08/09 15:50

ご回答ありがとうございます。わかりにくかったかもしれません。失礼しました。質問のコードはすべて同一のファイルでの話です。 Object.definePropertyではfoo,bar,fizzの三つが揃って、それを利用したら、ids.datasの中身を削除するという風にしたかったので、グローバル変数はややこしくなるので使わなかったと思います。 大幅にコードを変更してしまったため、問題の状況がよくわからなくなってしまいましたが、勘違いしていた点がわかりました。実のある勘違いではないですが、質問した手前スルーはないので書いておきます。 https://developer.chrome.com/extensions/runtime#event-onMessage 上記のchrome.runtime.onMessage.addListenerの説明では、「同じドキュメントに複数のonMessageリスナーがある場合、応答を送信できるのは1つだけです。」とあるため、 chrome.runtime.onMessage.addListener(msg, () => {if(msg.foo)}) chrome.runtime.onMessage.addListener(msg, () => {if(msg.bar)}) それぞれが別のメッセージを受け取る場合でもcallbackがどちらかしか使えないという頭があり、質問の最期のコードでsetTimeout(onMessage.addListenerのかわり)を一番外側にもってきましたが、以下で普通に行けたかと思います。 function p_wrapper(){ return new Promise(r => { chrome.runtime.onMessage.addListener((msg, sender, callback), () => {/同一ドキュメント内の二つ目のonMessage.addListener r(callback) }) }) } function p_wrapper2(){ return new Promise(r => { //Object.defineProperty(idsの処理 r('hoge') }) } Promise.all([p_wrapper(), p_wrapper2()]).then(msg => {console.log(msg)}) Chrome拡張関係ありました。だいぶ説明不足でした。些細な問題を一般化しすぎました。
kei344

2019/08/09 15:59

まだ質問が「受付中」になっていますが、どのように解決したのかを回答文に書き、それを持って一旦「解決済」にされてはいかがでしょうか。
navca

2019/08/19 12:31

お返事が遅れ大変失礼しました。はいそうします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問