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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア69612
0
このサイトでPromise勉強しました。
Qiita:Promiseとasync-awaitの例外処理を完全に理解しよう
投稿2017/06/08 07:31
総合スコア1013
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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総合スコア18402
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
総合スコア117039
0
便乗
- 同期処理であれば
throw new Error()
- コールバックを渡すタイプの非同期処理であれば
reject(new Error())
が一番分かりやすいかと思います。
投稿2017/06/08 22:07
総合スコア5223
0
Promice.reject()を実行するか、例外エラーを発生させるかのどちらかになるかと思います。
それで最後にcatch文でエラーを捕捉出来ます。
投稿2017/06/09 00:31
編集2017/06/13 20:00退会済みユーザー
総合スコア0
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/09 01:12