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

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

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

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

非同期処理

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

Q&A

解決済

6回答

24171閲覧

Promise then()を繰り返す場合の抜け方

tokyo

総合スコア35

JavaScript

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

非同期処理

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

0グッド

1クリップ

投稿2017/06/08 07:21

JavaScriptでPromiseのthen()を繰り返す場合、途中で抜けるにはどうしたらいいのでしょうか。
return false;ではだめなようでした。

JavaScript

1FuncHoge() 2.then(function(){ 3 console.log("1"); 4 return Promise; // ←ざっくり書いていますがPromiseオブジェクトをreturnしてます 5}) 6.then(function () { 7 console.log("2"); 8 if (hoge) { 9 return false; // 次のthenに行ってほしくないがこれではだめ。console.log("3")が実行される 10 } else { 11 return Promise; 12 } 13}) 14.then(function () { 15 console.log("3"); 16 return Promise; 17}) 18.then(function () { 19 console.log("4"); 20 return Promise; 21}); 22

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

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

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

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

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

guest

回答6

0

ベストアンサー

例外を使えばよいのでは。

【Promise.prototype.then() - JavaScript | MDN】
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

then() の引数として渡した関数が失敗状態 (rejected) の Promise が返した場合や、例外(エラー)が発生した場合は、失敗状態 (rejected) の Promise を返します。

投稿2017/06/08 07:26

kei344

総合スコア69364

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

0

投稿2017/06/08 07:31

kanimaru

総合スコア1013

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

0

Promiseのthenチェーンは基本的に一本道で、thenチェーンは最初から最後まで無条件に実行することを大前提で書くと思います。よって途中で中断させるならkei344さんがおっしゃるようにエラー中断することになると思います。エラー扱いなので当然ながらcatch節が実行されます。

途中で抜けるという意味が正常に中断させることであるとすればthenチェーンの中の任意のthen節で中断させることはできず、最後のthen節で制御を分岐させないといけないのではないでしょうか。

例えばPromiseを返すような関数群a,b,c,dがあったとして、あるケースだけbの後に中断したいなら

javascript

1a() 2.then(b) 3.then(() => { 4 if (...) { 5 c() 6 .then(d) 7 .then(e) 8 } 9}) 10.catch(...)

といった具合です。途中で抜けるというよりは、「抜けない場合の処理をthenチェーンの最後のthen節に(入れ子を一段深くする形で)記述する」という感じです。

正常処理としての制御ルートを変化させたい場合、ルートを変えれば変えるほどthenの入れ子構造は深くなっていくと思います。


余談:

途中で抜けることを素直に書く手段としては、例えばPromiseに加えて、co/generator function/yieldを使い、非同期処理をあたかも同期処理であるかのように記述する方法があります。(おそらくkanimaruさんが書かれているページと本質的に考え方は同じではないかと思いますが、coしか知らないので本当かどうか自信ないです)

それを使うとPromiseのthenチェーンはプログラムコード上では単純な文の羅列として書けます。このため、途中で制御を変えたければjavascriptとしてのreturnなどの制御文を普通に使えますし、例外はtry-catchで表現することもできます。あたかもマルチスレッドが利用できる言語で同期処理関数を利用して書いているかのように記述できるので、これはこれで一つの分かり易い方法ではないかと思います。

訂正1: 下記のコード例の文法がはちゃめちゃだったので訂正しました。スミマセン

javascript

1co(function*() { 2 const ra = yield a(); 3 ... 4 const rb = yield b(); 5 ... 6 if (...) return 7 ... 8 const rc = yield c(); 9 const rd = yield d(); 10 ... 11});

投稿2017/06/08 09:00

編集2017/06/08 15:03
KSwordOfHaste

総合スコア18392

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

0

かんがえ方はこうです

javascript

1<script src="https://www.promisejs.org/polyfills/promise-6.1.0.min.js"></script> 2<script> 3(function(){ 4 new Promise(function(resolver,rejector){ 5 setTimeout(function(){ 6 console.log("done_a"); 7 return resolver(this); 8 },1000); 9 }).then(function(){ 10 new Promise(function(resolver,rejector){ 11 setTimeout(function(){ 12 console.log("done_b"); 13 return resolver(this); 14 },1000); 15 }).then(function(){ 16 new Promise(function(resolver,rejector){ 17 setTimeout(function(){ 18 console.log("done_c"); 19 return resolver(this); 20 },1000); 21 }).then(function(){ 22 new Promise(function(resolver,rejector){ 23 setTimeout(function(){ 24 console.log("done_d"); 25 return resolver(this); 26 },1000); 27 }).then(function(){ 28 console.log("end"); 29 }).catch(function(){ 30 console.log("stop_d"); 31 }); 32 }).catch(function(){ 33 console.log("stop_c"); 34 }); 35 }).catch(function(){ 36 console.log("stop_b"); 37 }); 38 }).catch(function(){ 39 console.log("stop_a"); 40 }); 41})(); 42 43</script> 44

※上記各「done_」の後ろのreturn resolver(this);をreturn rejector(this);[
にすれば、その時点で終了となります

投稿2017/06/08 07:58

yambejp

総合スコア114572

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

0

便乗

日本語のコードで理解するPromise - Qiita

  • 同期処理であれば throw new Error()
  • コールバックを渡すタイプの非同期処理であれば reject(new Error())

が一番分かりやすいかと思います。

投稿2017/06/08 22:07

mpyw

総合スコア5223

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

0

Promice.reject()を実行するか、例外エラーを発生させるかのどちらかになるかと思います。
それで最後にcatch文でエラーを捕捉出来ます。

投稿2017/06/09 00:31

編集2017/06/13 20:00
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

tokyo

2017/06/09 01:12

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問