1

以下を考えると:

var doThings = (function ($, window, document) { 
  var someScopedVariable = undefined,
      methods,
      _status;

  methods = { 
    init: function () { 
      _status.getStatus.call(this);

      // Do something with the 'someScopedVariable'
    }
  };

  // Local method
  _status = { 
    getStatus: function () { 
      // Runs a webservice call to populate the 'someScopedVariable'

      if (someScopedVariable === undefined) { 
        _status.setStatus.call(this);
      }

      return someScopedVariable;

    },
    setStatus: function () { 
      $.ajax({
           url: "someWebservice",
           success: function(results){
              someScopedVariable = results;
           }
         });
    }
  };

  return methods;

} (jQuery, window, document));

someScopedVariable問題は明らかです。これは非同期の状況であり、未定義でなくなるまで待ってから続行したいと考えています。

jQuery の .when() -> .done() 遅延呼び出しを使用することを考えましたが、うまく動作しないようです。また、まだ定義されているかどうかを確認するだけのループを実行することも考えましたが、それはエレガントに見えません。

可能なオプション 1:

$.when(_status.getStatus.call(this)).done(function () {
        return someScopedVariable; 
});

可能なオプション 2 (ひどいオプション):

_status.getStatus.call(this)

var i = 0;
do {
  i++;
} while (formStatusObject !== undefined);

return formStatusObject;

更新: 説明するためにあまりにも多くのロジックを削除したと思われるため、一部を追加し直しました。これの目標は、このデータへのアクセサーを作成することでした。

4

3 に答える 3

4

ajax 呼び出しの完了/成功イベントを待つことをお勧めします。

  methods = { 
    init: function () { 
      _status.getStatus.call(this);
    },
    continueInit: function( data ) {
      // populate 'someScopedVariable' from data and continue init
    }
  };

  _status = { 
    getStatus: function () { 
      $.post('webservice.url', continueInit );
    }
  };
于 2011-06-01T15:31:00.737 に答える
1

JavaScriptはシングルスレッドで実行されている可能性が高いため、非同期リクエストが終了するのを待つためにinfiteループを使用してブロックすることはできません。JavaScriptエンジンは、スクリプトが終了するのを待ってから、ループで監視している変数を変更する非同期コールバックを呼び出そうとします。したがって、デッドロックが発生します。

2番目のオプションのように、全体でコールバック関数を使用するのが唯一の方法です。

于 2011-06-01T15:34:08.787 に答える
0

可能であれば、コールバックの使用に関する他の回答に同意します。何らかの理由でブロックして応答を待つ必要がある場合は、ループアプローチを使用しないでください。これは、可能な限り最悪の方法です。最も簡単なのはasync:false、ajax呼び出しでsetを使用することです。

http://api.jquery.com/jQuery.ajax/を参照してください

async-ブールデフォルト:trueデフォルトでは、すべての要求は非同期で送信されます(つまり、これはデフォルトでtrueに設定されています)。同期リクエストが必要な場合は、このオプションをfalseに設定してください。クロスドメインリクエストとdataType:「jsonp」リクエストは同期操作をサポートしていません。同期リクエストはブラウザを一時的にロックし、リクエストがアクティブな間はアクションを無効にする可能性があることに注意してください。

于 2011-06-01T15:34:57.127 に答える