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

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

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

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

非同期処理

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

Q&A

解決済

2回答

569閲覧

【Promise,callback】どちらが良いのか?

OOO_777

総合スコア50

JavaScript

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

非同期処理

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

0グッド

1クリップ

投稿2018/03/16 02:31

前提・実現したいこと

設定パターン1~2のコードがありますが、1はコールバック、2はプロミスで書いています。この場合どちらで書くべきでしょうか。
コールバックでも問題ないのか、それともプロミスで書いたほうが良いのか教えて頂ければ幸いです。

該当のソースコード

javascript

1//設定 パターン1 2const ChangePermission = (callback) => { 3 if('permissions' in navigator) { 4 navigator.permissions.query({name:'notifications'}).then((notificationPerm) => { 5 notificationPerm.onchange = () => { 6 if(notificationPerm.state === "granted"){ 7 console.debug('通知が許可に変更'); 8 callback(); 9 } 10 }; 11 }); 12 } 13};

javascript

1//設定 パターン2 2const ChangePermission = () => { 3 return new Promise((resolve, reject) => { 4 if('permissions' in navigator) { 5 navigator.permissions.query({name:'notifications'}).then((notificationPerm) => { 6 notificationPerm.onchange = () => { 7 if(notificationPerm.state === "granted"){ 8 console.debug('通知が許可に変更'); 9 resolve(); 10 } 11 }; 12 }); 13 } 14 }); 15};

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

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

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

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

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

guest

回答2

0

ベストアンサー

Promiseを使うことのメリット・デメリットは、以下のような感じだと考えています。

  • メリット:resolverejectという2つの状態を持てる、async-awaitを使ってすっきり書くこともできる、Promise.allPromise.raceなどで並列実行の管理も容易、自動で非同期になる
  • デメリット:IE 11などではPolyfillが必要、コールバックを同期実行することができない

今回の場合は、自分だったらPromiseで書いて、拒否された時にもきちんとrejectしておく、というようなコードを書くと思います(ブラウザ通知はIE 11にないので、そこは気にしなくても構わない場面ですし)。

投稿2018/03/16 02:48

編集2018/03/16 02:59
maisumakun

総合スコア145123

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

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

OOO_777

2018/03/16 03:19

ご回答ありがとうございます。 Promiseでのメリット、デメリット勉強になりました。 ありがとうございます。
guest

0

ぶっちゃけどっちでもいいです。
既存のライブラリや既存コードに合わせて統一するのが楽です。
callbackとpromiseの併用は寿命を縮めます。

promiseは配列の要素数分の非同期処理のループを作りたい、
みたいな状況でネストを発生させずに綺麗に書きやすい程度のメリットしかありません。
npmのasyncパッケージ等を上手く活用すればいつものコールバックで十分頑張れますからね。


そもそも1の書き方は駄目です。
コールバックを使う場合、第一引数はerrにしましょう。
(JSの非同期の処理はtry〜catchで補足出来ないので、第一引数をerrとして確実に分かるようにすべきという慣習があります)

JavaScript

1const ChangePermission = (callback) => { 2 // ガード節で抜けた方がネストが浅くなる + callbackの第一引数にerrを入れながら返す 3 if(!('permissions' in navigator)) { 4 callback(new Error('permissions is not in navigator.')); 5 } 6 navigator 7 .permissions 8 .query({name:'notifications'}) 9 .then((notificationPerm) => { 10 notificationPerm.onchange = () => { 11 if(notificationPerm.state !== "granted") return; 12 console.debug('通知が許可に変更'); 13 callback(null); 14 }; 15 }) 16 .catch(callback); 17 } 18};

質問文の例は終わり方が多いので、様々な状況に考慮する場合コードが増える傾向にあります。


promiseを使いつつ、ES2017で追加されたasync / awaitを利用することをオススメします。
内部でやり取りしているのはpromiseのインスタンスなので内部は非同期に変わりありませんが、
コード上は同期的で書けるのでわかりやすくなります。

(最後のonchangeのトリガーでresolveを返す設計上、妥協して結局promise返してますが…)

JavaScript

1const ChangePermission = async () => { 2 if('permissions' in navigator) { 3 throw new Error('permissions is not in navigator'); 4 } 5 const notificationPerm = await navigator.permissions.query({name:'notifications'}); 6 return new Promise((resolve, reject) => { 7 notificationPerm.onchange = () => { 8 if(notificationPerm.state !== "granted") return; 9 console.debug('通知が許可に変更'); 10 resolve(); 11 }; 12 }); 13};

投稿2018/03/16 03:11

miyabi-sun

総合スコア21158

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

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

OOO_777

2018/03/16 03:33

ご回答ありがとうございます。 そうなんですね、環境に合わせたほうがよいのですね。 「コールバックを使う場合、第一引数はerr」 「promiseを使いつつ、ES2017で追加されたasync / awaitを利用する」 上記ご指摘ありがとうございます。勉強になりました。
miyabi-sun

2018/03/16 03:36

あ、そうだ(唐突) コールバックは第一引数がerrになる関係で、 使う側は大抵コールバック関数の1行目が`if (err)`で始まる事になります。 つまりコードリード時はプチ邪魔な存在。 どちらでも良い状況ならまずPromiseを使う事を考えると良いでしょう。
OOO_777

2018/03/16 03:55

なるほど!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問