2016-05-13 5 views
1

JavaのPromiseオブジェクトの値を同期的に取得する必要があります。Javascript Promiseの値を同期的に取得する

PromiseオブジェクトはJavascriptで動作し、その利点と、thenメソッドで値を処理する方法は分かっていますが、特にNode.jsの使用例があります(ただし、これはブラウザエンジンにも当てはまります)。 )ただし、値を返す必要がありますが、プロミスオブジェクトを返すAPIを呼び出していて、そのAPIまたはコンシューマAPIのシグネチャを変更することはできません。

たとえば、Java言語では、アクションを完了するために必要な場合(実行をブロックする)を待機させ、その結果を戻す方法があります(get())。待ち時間がタイムアウトした場合は、でも起動するまでの最大待ち時間はTimeoutExceptionです。

私が持っている問題は、このようなものです:

api1.setCallBackThatHasToReturnANoPromiseValue(
    function(p1, p2) { 
    return api2.getPromisedValue(p1,p2)  // This returns a Promise 
             .get() // -> but something like this 
               // could get the value in a sync way 
    } 
); 

私は非同期プログラミングでこれを解決することができれば、誰かが私に言うことはできますか?

非同期コードで修正できる特定の問題にかかわらず、Promiseの値を同期方法で取得する方法があります(実行をブロックし、すべてのパフォーマンスの問題があることがわかっています。 "bla bla ...")。

+2

あなたはこれらの概念について混乱していると思います。コード*は* asyncなので、約束が必要です。それが同期的に行えるのであれば、約束は始める必要はありません。これがNodeJSにある場合は、多くのメソッドの同期バージョンがありますが、それが利用できない場合、答えは「いいえ」です。 –

+1

この約束は事実上非同期の世界にあります。何かが非同期にトリガーされると、それを再び同期させる方法はありません。 –

+0

@squint私が言ったように、私は2つの異なるAPIを扱っているので、私は約束を使用し、もう1つはそうでないという事実を変更することはできません。サンプルコードを見て、それを解決する方法を教えてください。 – Mrdev

答えて

2

の同期方法でJavascript Promiseオブジェクトの値を取得する必要があります。

できません。 APIが、操作が非同期であるために約束を返した場合。あなたの関数が返ってきた時点では、その値はまだ知られていません.Javascriptは結果を待つためのメカニズムを提供していません。

代わりに、非同期応答を設計し、呼び出し側が非同期応答をコードする必要があります。既に約束を使用しているので、呼び出し元が約束のために.then()ハンドラを使用して非同期の結果にアクセスする必要があり、APIコールが既に返されてから後で、.then()ハンドラが将来呼び出されることを意味します。

ブラウザとnode.jsのJavascriptは基本的にJavaとは異なることを理解することが重要です。これらのJavascript環境は、シングルスレッドでイベント駆動型です。つまり、ブロックすることはできませんし、何かが起こるのを待ってから戻ることを意味します。代わりに、戻ってイベントキューを実行させて、非同期の結果を最終的に処理してコールバックをトリガーする必要があります。あなたがブロックして結果を待っているとしたら(ある人が別の言語で使用するかもしれないsleep()呼び出しをシミュレートするために数秒間ループするビジーなループを作ろうとしている人がいる)、結果はできないのでデッドロックになりますあなたがブロックを止めるまで処理されますが、結果が得られるまでブロッキングを止めることはありません。あなたは無限ループに終わるでしょう。

代わりに、Javascriptでの非同期応答をプレーンコールバックまたは約束とそれに関連する.then()ハンドラを使用してプログラミングする方法を学ばなければなりません。そして、その非同期結果のすべての消費者はそれが非同期であり、それに応じてプログラムであることを知る必要があります。


さらに、約束は将来価値を表すものです。値が準備されているか、エラーが発生したときに呼び出される.then()ハンドラを使用してアクセスするだけです。約束から価値を得るための同期的な方法はありません。

1

(Babeljsまたはライブラリ経由で)ES2016(ES7)機能を使用できる場合は、async-awaitを使用できます。

async-awaitを使用すると、関数を非同期コードとして定義し、awaitキーワードを使用して非同期関数からの応答を待機します。非同期関数は約束を返す必要があります。 Async-awaitを使用すると、同期しているかのように非同期コードを記述できます。

+0

私は今ES7を使用することはできませんが、素晴らしいですね、Node.jsの次の安定版ですぐにこれらの機能が利用できることを願っています。 – Mrdev

+0

@Mrdev:確かにこれは素晴らしい機能ですが、この機能が今日利用可能であっても、あなたの現在の状況には役立ちません。 @ kevintechieが書いたように、* "非同期関数は約束を返す必要がある" *。これは構文砂糖だけであり、あなたがすでにできることに何も追加しません。それだけでそれをきれいにする。 –

関連する問題