非同期呼び出しから応答を返すにはどうすればよいですか?
P粉722409996
P粉722409996 2023-10-08 20:41:15
0
2
543

非同期リクエストを行う関数fooから応答/結果を返すにはどうすればよいですか?

コールバックから値を返し、その結果を関数内のローカル変数に代入してその変数を返そうとしましたが、これらのメソッドはいずれも実際には応答を返しません。すべてunknownまたはその他のメソッドを返します。その他の変数resultの初期値は次のとおりです。

コールバックを受け入れる非同期関数の例(jQuery のajax関数を使用):

リーリー

Node.js を使用した例:

リーリー

thenプロミス ブロックを使用した例:

リーリー


P粉722409996
P粉722409996

全員に返信 (2)
P粉477369269

コードで jQuery を使用しない場合は、この回答が役に立ちます

コードは次のようになります:

リーリー

Felix Kling は、AJAX に jQuery を使用する人々向けに素晴らしい回答を書いてくれましたが、私は jQuery を使用しない人々向けに代替案を提供することにしました。(

新しい

fetchAPI、Angular または Promise を使用している人のために、以下に別の回答を追加しました)

あなたが直面している問題

これは、別の回答の「質問の説明」の短い要約です。これを読んでもよくわからない場合は、その回答を読んでください。

AJAX の

A

は、asynchronousを表します。これは、リクエストの送信 (または応答の受信) が通常の実行フローから削除されることを意味します。あなたの例では、.sendはすぐに戻り、 code>successコールバックreturn result; ## として渡した関数を呼び出す前に次のステートメントが実行されます。 #。これは、戻ったときに、定義したリスナーがまだ実行されていないこと、つまり、返された値がまだ定義されていないことを意味します。

これは簡単な例えです:

リーリー ######(バイオリン)######

a=5

部分はまだ実行されていないため、返される

a値はunknown

です。 AJAX は、サーバーがブラウザに値を伝える前に値を返すように動作します。

この問題に対する考えられる解決策の 1 つは、計算完了後にプログラムに何を行うかを指示するコードをリアクティブに記述することです。リーリーこれはCPS

と呼ばれます。基本的に、完了時に実行するアクションを

getFiveに渡し、イベントが完了したときにどのように反応するかをコードに指示します (AJAX 呼び出し、この場合はタイムアウトなど)。

使用方法:

リーリー「5」が画面に表示されます。 ###(バイオリン)###。###可能な解決策###この問題を解決するには、基本的に 2 つの方法があります:

AJAX 呼び出しを同期にします (これを SJAX と呼びます)。

コールバックで適切に動作するようにコードをリファクタリングします。###1。同期 AJAX - やめてください。 !

同期 AJAX に関しては、

やめてください。

Felix の答えは、これがなぜ悪い考えなのかについて、いくつかの説得力のある議論を示しています。全体として、サーバーが応答を返すまでユーザーのブラウザがフリーズし、非常に悪いユーザー エクスペリエンスが作成されます。その理由を説明する MDN の別の短い要約を次に示します。

これを
    行う必要がある場合は、フラグを渡すことができます。
  1. 具体的な方法は以下の通りです
  2. :
  3. リーリー ###2。組織再編コード
関数がコールバックを受け入れるようにします。コード例では、

foo

がコールバックを受け入れるようにできます。

fooが完了したときにreact

を行う方法をコードに伝えます。

###それで:### リーリー ###なる:###リーリー

ここでは匿名関数を渡していますが、既存の関数への参照も同じように簡単に渡すことができ、次のようになります。 リーリー

このタイプのコールバック設計を実現する方法の詳細については、Felix の回答を確認してください。

次に、対応する操作を実行するために foo 自体を定義しましょう

リーリー ######(バイオリン)######

これで、

foo関数が、AJAX が正常に完了したときに実行するアクションを受け入れるようになりました。応答ステータスが 200 でないことを確認し、適切なアクション (失敗ハンドラーの作成など) を実行することで、この機能をさらに拡張できます。それは私たちの問題を効果的に解決しました。

これをまだ理解できない場合は、

MDN の AJAX スタート ガイドを読んでください。

いいねを押す+0
    P粉515066518

    ###質問###

    Ajax

    Aasynchronousを表します。これは、リクエストの送信 (または応答の受信) が通常の実行フローから削除されることを意味します。あなたの例では、$.ajaxはすぐに戻り、successコールバックとして渡す関数が呼び出される前に、次のステートメントreturn result;が実行されます。これは、同期ストリームと非同期ストリームの違いをより明確にするための例えです:

    同期

    あなたが友人に電話して、何か情報を見つけてもらうように頼んだと想像してください。時間はかかるかもしれませんが、友人が必要な答えをくれるまで、電話のそばで宇宙を見つめながら待ちます。

    「通常の」コードを含む関数呼び出しを行う場合にも、同じことが起こります。

    リーリー

    findItem

    の実行には長い時間がかかる場合がありますが、var item = findItem();の後のコードは、関数が結果を返すまで待機する必要があります。非同期

    あなたはまた同じ理由で友達に電話をかけます。しかし、今回はあなたが不安なので、携帯電話

    に折り返し電話してくださいと伝えます。電話を切り、家を出て、予定していたすべてのことを行います。友人があなたに折り返し電話をかけてきたら、あなたは彼があなたにくれた情報を処理していることになります。

    これはまさに、Ajax リクエストを行うときに起こることです。リーリー応答を待たずに、すぐに実行を継続し、Ajax 呼び出しの後にステートメントを実行します。最終的に応答を取得するには、応答の受信後に呼び出される関数、コールバックを提供する必要があります (何かお気づきですか? コールバック?)。この呼び出しの後のステートメントは、コールバックが呼び出される前に実行されます。

    ###解決###

    JavaScript の非同期の性質を活用してください。

    一部の非同期操作は (「Ajax」のように) 同期操作を提供しますが、特にブラウザーのコンテキストでは、その使用は一般に推奨されません。

    なぜそれが悪いのですか?

    JavaScript はブラウザの UI スレッドで実行され、長時間実行されるプロセスによって UI がロックされ、応答しなくなる可能性があります。また、JavaScriptの実行時間には上限があり、ブラウザは実行を継続するかどうかをユーザーに尋ねます。これらはすべて、非常に悪いユーザー エクスペリエンスにつながる可能性があります。ユーザーは、すべてが適切に動作しているかどうかを判断できません。さらに、インターネット速度が遅いユーザーの場合、影響はさらに大きくなります。

    以下では、相互に構築される 3 つの異なるソリューションを紹介します。

    async/await

    との約束 (ES2017、トランスパイラーまたはリジェネレーターを使用している場合は古いブラウザーで動作します)

    • コールバック(ノードで人気)Promise と
    • then()
    • (ES2015、多くの Promise ライブラリのいずれかを使用している場合は古いブラウザでも動作します)
    • 3 つの機能はすべて、現在のブラウザと Node 7 で使用できます。
    • ES2017: プロミスに

    async/await を使用する


    ECMAScript の 2017 リリースでは、非同期関数の

    構文レベルのサポートが導入されました。asyncawait

    を使用すると、「同期スタイル」で非同期に書くことができます。コードは依然として非同期ですが、読みやすく理解しやすくなっています。

    async/awaitPromise に基づいて構築:async関数は常に Promise を返します。awaitPromise を「ラップ解除」し、解決された Promise の値を生成するか、Promise が拒否された場合はエラーをスローします。

    IMPORTANT:awaitは、JavaScript モジュール。トップレベルのawaitはモジュールの外部ではサポートされていないため、asyncコンテキスト (モジュールを使用しない場合)。

    asyncawaitについて読むことができます。これは、上記の

    遅延

    関数findItem()の詳細を示す例です:リーリー現在の

    ブラウザ

    およびnodeバージョンはasync/awaitをサポートしています。regenerator(または regenerator を使用するツール) を使用してコードを ES5 に変換し、Babelなどの古い環境をサポートすることもできます。

    関数にコールバックを受け入れさせます

    コールバックは、関数 1 が関数 2 に渡されるときを指します。関数 2 は、準備ができたら関数 1 を呼び出すことができます。非同期プロセスのコンテキストでは、非同期プロセスが完了するたびにコールバックが呼び出されます。通常、結果はコールバックに渡されます。

    質問の例では、

    foo

    にコールバックを受け入れさせ、それをsuccessコールバックとして使用できます。したがって、この### リーリー ###なりました### リーリーここでは「インライン」関数を定義しますが、任意の関数参照を渡すことができます:リーリー

    foo

    自体は次のように定義されます:

    リーリー

    callbackは、呼び出し時にfoo

    に渡した関数を参照し、それを

    successに渡します。つまり。 Ajax リクエストが成功すると、$.ajaxcallbackを呼び出し、応答をコールバックに渡します (このように定義しているため、resultで参照できます)コールバック)。応答をコールバックに渡す前に処理することもできます。リーリーコールバックを使用したコードの記述は、見た目よりも簡単です。結局のところ、ブラウザーの JavaScript は主にイベント駆動型 (DOM イベント) です。 Ajax 応答の受信は単なるイベントです。 サードパーティのコードを使用する必要がある場合は問題が発生する可能性がありますが、ほとんどの問題はアプリケーション フローを考えるだけで解決できます。


    ES2015:then()的 Promise >

    を使用

    Promise APIは ECMAScript 6 (ES2015) の新しい機能ですが、すでに優れたブラウザ サポートを備えています。標準の Promises API を実装し、非同期関数の使用と構成を簡素化するための追加メソッドを提供するライブラリも多数あります (例:Bluebird)。

    Promise は、将来の値のコンテナです。 Promise が値を受け取るか (resolved)、またはキャンセルされると (rejected)、その値にアクセスしたいすべての「リスナー」に通知します。

    通常のコールバックと比較した利点は、コードを分離でき、記述が容易であることです。

    これは Promise の使用例です:

    リーリー リーリー
    いいねを押す+0
      最新のダウンロード
      詳細>
      ウェブエフェクト
      公式サイト
      サイト素材
      フロントエンドテンプレート
      私たちについて 免責事項 Sitemap
      PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!