検索

ホームページ  >  に質問  >  本文

javascript - Nodejs が非同期実装を実装するときに発生する問題

たとえば、a、b、c という 3 つの関数があり、いずれも同期操作を実行します。簡略化するために、同期操作を単純化しました。

リーリー

a() の実行の出力は 2
ですが、c 関数が同期関数ではなく非同期操作を実行する場合、たとえば

リーリー

a() を実行するとき、2 を正しく出力したい場合は、promise または async を通じて c をカプセル化する必要があります。
と同様 リーリー

c は非同期関数になるため、b は c を呼び出す必要があり、b も非同期に変更する必要があり、同様に a も非同期に変更する必要があります。 リーリー

a().then(関数(データ) {

リーリー

}) このようにして、2

を出力できます

2を正しく出力するために、aとbの両方を変更しましたが、aとbの変更を避けて正しい出力を実現する他の方法はあるでしょうか?

最初にコードを書いたときは非同期の状況を考慮していなかったので、a と b のような関数は別のファイルに分散されており、それらの関数はたくさんあります。ここで、c が非同期操作を実行できるようにするには、次のようにします。変更するのは難しすぎます。他に良い方法はありますか?


以下は新しく追加された質問です

上記の問題は、以下の回答でPromiseオブジェクトを直接返すことで解決できますが、実際のコード構造は次のようになります

リーリー
この方法に従う場合、a と b の return メソッドを変更する必要があります。

a と b が Promise オブジェクトを返せるようにするには、

方法があるかどうかわかりません。このような構造の a および b 関数を変更せずに正しい出力を実現します。

黄舟黄舟2730日前891

全員に返信(6)返信します

  • 阿神

    阿神2017-07-03 11:43:44

    申し訳ありませんが、ノードは明示的に非同期であるため、関数を同期から非同期に変更すると、それに依存する関数も変更する必要があります。リファクタリング時には確かに頭の痛い問題ですが、それでも変更する必要があります。我慢して変えましょう。

    async キーワードを必要としない fibjs のようなリファクタリングは、c を変更する場合、暗黙的な非同期を示す必要がないため、a と b を変更する必要はありません。

    返事
    0
  • PHP中文网

    PHP中文网2017-07-03 11:43:44

    Promise についてはまだ十分に理解できません。ここでb()a()を変更する必要はありません。

    この Promise を関数 c,只需要返回一个promise对象,经过函数b的时候,直接同步返回这个Promise对象,不需要改动函数b使其为异步函数,因为异步操作是在函数c中,b中只进行了同步操作。此时需要在函数a でキャプチャするには、コードを次のように変更できます

    リーリー

    では、この関数 a(),b() が非同期操作の戻り値を処理しない場合、なぜ Async 関数に変更する必要があるのでしょうか?

    返事
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-07-03 11:43:44

    http://fibjs.org/docs/manual/... を試して、同期に直接変換できます

    返事
    0
  • 滿天的星座

    滿天的星座2017-07-03 11:43:44

    画面を見つめて何度も下書きをしたのですが、結局失敗してしまいました

    JS で現在の関数をブロックしながら、時間内に Promise の解決を実行する方法は思いつきません。失敗のアイデアは次のとおりです

    リーリー

    問題は、while(c_result===null && n++<100){}阻塞了函数c_sync, 但是也阻止了.thenシングルスレッドの非同期メカニズムにより、コールバックが実行されるにもかかわらず、スレッドがビジー状態の場合、コールバックがキューにジャンプできず、その結果 c_result が何もできなくなることです。ループの実行中に変数 m に代入されるため、ループを終了することはできません。

    しかし、この質問は非常に興味深いと思います。著者は外部バイナリライブラリを通じてローカルブロッキングの問題を解決しました。

    http://blog.csdn.net/xingqili...

    私の理解は次のとおりです:

    js エンジン自体のイベント ループに基づいて、特定のブロックをブロックすることはできません。js コードの場合、エンジンのイベント ループは下部にありますが、外部バイナリ モジュールの場合は、それ自体をブロックできます。そして、JS エンジンのイベント ループが毎回イベント キューを完全に横断するようにします。これにより、JS エンジン内の新しいイベントが独自のブロック期間中に処理できるようになります。

    返事
    0
  • 巴扎黑

    巴扎黑2017-07-03 11:43:44

    Let a() 出力 Promise は確かに私が述べた問題を解決することができます
    しかし、実際にコードを変更してみると、ほとんどのコードの構造は上記の問題とは異なり
    、新しく追加された以下の構造であることがわかりました

    リーリー

    返事
    0
  • 世界只因有你

    世界只因有你2017-07-03 11:43:44

    敬意を表しますが、あなたは、node.js のイベント ループ メカニズムとイベント コア モジュールを深く理解していません。
    promise や aysnc/await は確かに現在非同期プロセス制御を扱うのに主流ですが、それがないとできないというわけではありません。このような単純な問題はイベント メソッドに戻って処理できます。

    リーリー

    返事
    0
  • キャンセル返事