web-dev-qa-db-ja.com

JavaScript:Ajaxリクエスト後のグローバル変数

質問はかなりシンプルで技術的です:

_var it_works = false;

$.post("some_file.php", '', function(data) {

     it_works = true;

});

alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself)
_

私が達成したいのは:

_alert(it_works); # true
_

それを行う方法はありますか?そうでない場合、$.post()は_it_works_に適用される値を返すことができますか?

47
Gal

期待されるのは、synchronousblocking)タイプのリクエストです。

var it_works = false;

jQuery.ajax({
  type: "POST",
  url: 'some_file.php',
  success: function (data) {
    it_works = true;
  }, 
  async: false // <- this turns it into synchronous
});​

// Execution is BLOCKED until request finishes.

// it_works is available
alert(it_works);

リクエストはasynchronousnon-blocking)bydefaultこれは、ブラウザが作業を続行するために完了するのを待たないことを意味します。これが、アラートが間違った結果になった理由です。

さて、 jQuery.ajax オプションでリクエストをsynchronousに設定できます。つまり、スクリプトは実行のみを継続します afterリクエストは終了しました。


[〜#〜] recommended [〜#〜]方法は、しかし、refactorコードが、リクエストが終了するとすぐにデータがcallback関数に渡されるようにします。実行をブロックすると、受け入れられないUIをブロックすることになるため、これが推奨されます。次のようにしてください:

$.post("some_file.php", '', function(data) {
    iDependOnMyParameter(data);
});

function iDependOnMyParameter(param) {
    // You should do your work here that depends on the result of the request!
    alert(param)
}

// All code here should be INDEPENDENT of the result of your AJAX request
// ...

非同期プログラミングはやや複雑です複雑です要求文に従うのではなく、関数にカプセル化されます。 ただし、ユーザーエクスペリエンスが可能なリアルタイム動作大幅に改善されました。サーバーやネットワークの停滞は見られないため、ブラウザーはクラッシュしたかのように動作します。 同期プログラミングは無礼および人が使用するアプリケーションでは使用しないでください

ダグラス・クロックフォード(- YUI Blog

88
gblazex

AJAXは、非同期JavaScriptおよびXMLの略です。したがって、サーバーへのポストは、関数の残りの部分と非同期になります。代わりにこのようなコードを試してください(略記$.postより長い$.ajaxを呼び出して、asyncオプションを追加します)。

var it_works = false;

$.ajax({
  type: 'POST',
  async: false,
  url: "some_file.php",
  data: "",
  success: function() {it_works = true;}
});

alert(it_works);

お役に立てれば!

6
mattbasta

あなたの問題は単なる並行性の問題のようです。 post関数はコールバック引数を使用して、ポストが終了したときに通知します。このようなグローバルスコープでアラートを作成することはできず、投稿が既に終了していることを期待できません。コールバック関数に移動する必要があります。

5
Hosam Aly

コードが失敗する理由は、post()がサーバーへの 非同期 要求を開始するためです。つまり、post()は、要求が完了するとすぐにnotを返します。

必要なのは、リクエストが同期し、リクエストが完了するまで現在のスレッドをブロックすることです。したがって、

var it_works = false;

$.ajax({
  url: 'some_file.php',
  async: false,  # makes request synchronous
  success: function() {
    it_works = true;
  }
});

alert(it_works);
2
Jesse Dhillon