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

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

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

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

非同期処理

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

1210閲覧

【Promise】2つのプロミスを連続して使用する場合

OOO_777

総合スコア50

JavaScript

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

非同期処理

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2018/03/16 04:40

前提・実現したいこと

Promise処理で設定1、設定2のコードを連続で使用したい場合、
使用1に書いてみたのですが、こちらの記載で問題ないでしょうか。
もう少し簡潔にできる、何かが抜けている等がありましたら、教えて頂ければ幸いです。

該当のソースコード

javascript

1// 設定1 2const readScript = () => { 3 return new Promise((resolve, reject) => { 4 const script = document.createElement('script'); 5 script.setAttribute('src', 'test.js'); 6 script.setAttribute('charset', 'utf-8'); 7 document.getElementsByTagName('body')[0].appendChild(script); 8 script.onload = script.onreadystatechange = () => { 9 if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') { 10 resolve('成功1'); 11 } 12 }; 13 }); 14};

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('成功2'); 10 } 11 }; 12 }); 13 } 14 }); 15};

javascript

1// 使用1 連続で使用してみた場合 2readScript() 3 .then((value) => { //スクリプト読み込み後 4 console.debug(value); 5 ChangePermission() 6 .then((value) => { //通知許可時 7 console.debug(value); 8 //行いたい処理 9 }).catch((error) => { 10 console.debug(`ChangePermission ${error}.`); 11 }); 12 }).catch((error) => { 13 console.debug(`readScript ${error}.`); 14 });

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

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

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

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

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

guest

回答2

0

ベストアンサー

??「プロデューサさんはpromise.thenの使い方がまだまだなってないですね!
……しょうがありません。このカワイイぼくが教えて差し上げましょう!

というわけで、promise.thenの解説です。
promise.thenはちょっと特殊な挙動をする事になります。

  • 普通に値を返す: resolve(return-value)として処理
  • 例外を返す: reject(throw-error)として処理
  • Promiseを返す: promiseの処理を継続させ、結果(resolve, reject)により分岐

従って、最初のthenはすぐにthenで返した方が綺麗なコードになります。

JavaScript

1// 使用1 連続で使用してみた場合 2readScript() 3 .then(value => { //スクリプト読み込み後 4 console.log("ReadScript successful"); 5 console.debug(value); 6 return ChangePermission(); 7 }) 8 .then(value => { 9 console.log("ChangePermission successful"); 10 console.debug(value); 11 }) 12 .catch(error => { 13 console.debug(error); 14 });

こっちのほうが上から流れるような処理順番を綺麗に表現できてると思います。

質問文の使用例1はどの失敗がどのcatchで補足出来るかを細かく指示できますが、
処理が増えるとネストしまくりでpromiseのメリットが殆ど残ってないように思えますからね。


おまけ
既存のコードをざっとレビューしてみました。

  • 1行目が即リターンなアロー関数は{}を抜いた方が簡素になる
  • if文は長いコードを包まずに1〜2行の動作に徹した方が良い、主な用途はガード節
  • readScriptがtest.jsを決め打ちで読み込み始めるのはどうよ?引数で受け取るようにしてみたらどう?
  • navigatorがpermissionsプロパティを持ってない時のハンドリングが未修正

投稿2018/03/16 05:01

miyabi-sun

総合スコア21158

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

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

OOO_777

2018/03/16 08:23

ご回答ありがとうございます。 Promise.thenのご説明、コードレビューありがとうございます。 コードレビューに記載してあるもの全てを取り入れたいと思います。 2点質問をさせて頂きたいのですが、 1:return ChangePermission(); ←この処理が終了した際に動作させたい処理を記述する場合は、二番目のthenの中に記述をすればいい、という認識で問題ないでしょうか。 2:catchは最初にエラーになった方の値を返す、という認識で問題ないでしょうか。
miyabi-sun

2018/03/16 08:41

1. そのとおり Promiseというのは「実行中だよ」というステートをまるっと含んだインスタンスと理解してください。 `.then`で繋ぐと、「既に完了済み」もしくは「実行中→完了済み」になったら実行してねという風に 子供のお使いの内容を予め紙に書いて渡すような宣言の仕方になります。 使用例1はpromiseをreturnしていないので、これ以上thenで繋ぐ事は出来ません。 2. そうです。 try〜catch構文と同じようなものですね。 Promise内で動作中の関数がrejectを返した場合、内部パラメータは「実行失敗」になります。 実行失敗になると、以降つないでいる全ての`.then`は実行されず、一度だけ`.catch`を実行して完了します。
OOO_777

2018/03/16 08:52

前回の質問に続きご回答頂きありがとうございます。 とても勉強になりました!
guest

0

javascript

1const readScript=()=>{ 2 return new Promise((resolve)=>{ 3 setTimeout(() =>{console.log(1);resolve('hoge');}, 200) 4 }); 5}; 6const ChangePermission=()=>{ 7 return new Promise((resolve)=>{ 8 setTimeout(() =>{console.log(2);resolve('fuga');}, 100) 9 }); 10}; 11
  • thenで処理

javascript

1readScript().then(result=>{ 2 ChangePermission().then(result=>{ 3 console.log(result); 4 }); 5 console.log(result); 6});
  • async,awaitで処理

javascript

1(async ()=>{ 2 console.log(await readScript()); 3 console.log(await ChangePermission()); 4})(); 5

投稿2018/03/16 05:37

yambejp

総合スコア114784

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

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

OOO_777

2018/03/16 08:53

ご回答ありがとうございます。 他の書きかたも記載して頂きありがとうございます。 参考にさせて頂ければと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問