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

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

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

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

JavaScript

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

Q&A

解決済

3回答

4427閲覧

JavaScriptのPromiseのresolveを引数の関数外から呼ぶ方法を知りたいです

d415uk35470

総合スコア45

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

JavaScript

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

0グッド

0クリップ

投稿2017/03/12 01:10

JavaScriptのPromiseのresolveを引数の関数外から呼ぶ方法を知りたいです。一応動作はさせられたんですが明らかにイレギュラーな使い方なので、もっと良い方法があれば知りたいです。

まず通常の例です。foo.bar()を呼び出すと、Promiseを返し、1000ms後に完了したいとします。
この例は動作します。

JavaScript

1class Foo{ 2 bar(){ 3 return new Promise((resolve)=>{ 4 setTimeout(()=>{ resolve() }, 1000 ); //1000msかかる処理があるとする 5 }); 6 } 7}

次に、動作しない例です。こういうことがしたい、というイメージです。
つまりnew Promise()に渡す無名関数に何でもつっこむのが嫌になった時に、後で別の関数からresolveを呼び出したいです。
なぜそう思ったかというと、その無名関数が巨大になったり、外から中断したい可能性のあるいくつかの非同期実行される関数を経て、最終的にresolveを呼びたい(または中断された場合には呼ばない)ということがしたかった、というのが理由です。

JavaScript

1class Foo{ 2 bar(){ 3 this.promise = new Promise((resolve)=>{}); //とりあえずpromiseを保持しておく 4 setTimeout(this.onTimeout.bind(this),1000); //1000msかかる処理があるとする 5 return this.promise; 6 } 7 onTimeout(){ 8 //処理完了 9 this.promise.resolve(); //そのようなメソッドは存在しないのでエラーです 10 } 11}

きれいではない方法ですが、動作をさせることができたサンプルです。

JavaScript

1class Foo{ 2 bar(){ 3 this.promise = new Promise((resolve)=>{ 4 this.resolveFunction = resolve; //resolveも保持しておく 5 }); //とりあえずpromiseを保持しておく 6 setTimeout(this.onTimeout.bind(this),1000); //1000msかかる処理があるとする 7 return this.promise; 8 } 9 onTimeout(){ 10 //処理完了 11 this.resoveFunction.call(promise); //一応できた 12 } 13}

どう見てもイレギュラーな方法なので、良い書き方があれば知りたいです。

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

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

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

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

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

guest

回答3

0

、外から中断したい可能性のあるいくつかの非同期実行される関数を経て、最終的にresolveを呼びたい(または中断された場合には呼ばない)ということがしたかった

上記のしたいことがPromiseの役割です。
したがって、そもそも意味が無いことをしているのかもしれません。
もっと具体的に詰まっているコードを示していただいたほうが回答しやすいかもしれません

その無名関数が巨大になったり

無名関数のコードが巨大になってしまうならきちんと名前をつけて関数分割してあげて下さい。
無名関数だらけだと後々コードを読むのが困難になります。

以下のPromiseに関するドキュメントを一通り読むことをオススメします
http://azu.github.io/promises-book/

投稿2017/03/12 03:02

編集2017/03/12 04:40
m0a

総合スコア708

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

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

d415uk35470

2017/05/01 20:58

なるほど、その状況自体がすでに良くない、ということですね。良い指摘ありがとうございます。設計思想を再勉強してみます。ありがとうございます。
guest

0

例示されたコードでPromiseを使う意図が分かりませんでした。
もう少し、意味のおるコードを出した方が的確なアドバイスが付くと思います。

関数外から関数を呼ぶだけなら、コールバック関数を外部スコープに置く方法が第一に考えつきます。

JavaScript

1class Foo{ 2 bar(){ 3 return new Promise(this.onTimeout).then(this.resolve); 4 } 5 onTimeout (resolve) { 6 setTimeout(resolve, 1000); 7 } 8 resolve () { 9 sonsole.log('1 second later'); 10 } 11}

Re: terutaka-kondo さん

投稿2017/03/18 04:42

think49

総合スコア18162

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

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

d415uk35470

2017/05/01 21:00

確かに、例示したコードが良くなかったように思います。ご指摘ありがとうございます。 該当のメソッドを呼び出して完了待ちをしている間に、何かしら外から任意のタイミングで中断したい、そして中断した場合にはresolveのfunctionではなくrejectのfunctionを呼びたい、という感じでした。
guest

0

ベストアンサー

きれいではない方法ですが、動作をさせることができたサンプルです。
どう見てもイレギュラーな方法なので、良い書き方があれば知りたいです。

Promiseを拡張したDeferredというものが該当します。
考え方はterutaka-kondoさんの考えられた方法と余り変わりません。

https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred
詳しくは、この記事を読んでください。
polyfillを見ると考え方が一緒なのが分ります。

投稿2017/03/17 13:25

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

d415uk35470

2017/05/01 20:57

なるほど!jQuery.Deferredは以前から使っており、インスタンスを保持して後から使う、ということをするケースがあったので、同様のことをしたい場合はどうしたら、となって質問を投稿しました。 拡張したDeferredを考えた人がいるということは、そうしたいというシーンが生まれること自体はあながち完全に間違った状態である、ということではないということかなと理解しました。(とはいえ他の方が書いていただいているように、理想的な状態ではないのかもしれません。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問