0

ここにJavaScript関数があります:

  function getValue(key) {
    var value;
    switch(_options.myType){
      case "cookie":
        value = readFromCookie(key);
        break;
      case "localStorage":
        value = readFromLocalStorage(key);
        break;
      case "db":
        //return value from the server
        // how do I wait for the result?
        $.ajax({
            type: "GET",
            url: "123",
            data: { .... },
            success: function(data){
               value = data; 
            }
        });
        break;
    }
    return value;
  };

ajax リクエストを送信する場合、ajax リクエストが完了するまで待つ必要があります。どうすればいいですか?

値を計算せずに関数を終了できないわけではありません。つまり、後で値を返す関数をsuccess:ハンドラー内に配置することはできません (または、何か理解できないのでしょうか?)。したがって、関数内で計算する必要がありますgetValue()

アップデート

PSsuccess:では、ハンドラー内でコールバックを使用できるようにコードをリファクタリングするにはどうすればよいですか? コードの 2 番目の部分は次のとおりです。

MyClass123.prototype.myMethod = function(value) {
      //..............
      var var1 = this.getValue("key1");
      if (var1 == "123") { ... }
      else { .... }
      //..............
    }
  };
4

3 に答える 3

8

以下のフォローアップを参照してください

ajax リクエストを同期化することもできますが、それは一般的に悪い考えです (jQuery はそれをサポートしなくなります)。

代わりに、getValueコールバックを受け入れるようにします。

function getValue(key, callback) {
   switch(_options.myType){
     case "cookie":
       setTimeout(function() {
           callback(readFromCookie(key));
       }, 0);
       break;
     case "localStorage":
       setTimeout(function() {
           callback(readFromLocalStorage(key));
       }, 0);
       break;
     case "db":
       //return value from the server
       // how do I wait for the result?
       $.ajax({
           type: "GET",
           url: "123",
           data: { .... },
           success: function(data){
              callback(data);
           }
       });
       break;
   }
}

およびコールバックに を使用setTimeoutしていることに注意してください。なんで?ifはその値を非同期的に返す可能性があるため、常にそうする必要があります。タイムアウトを使用すると、制御がブラウザーに返されたら、できるだけ早くそれを実行するようブラウザーに要求します (ただし、通常は 5 ~ 10 ミリ秒以上に制限されます)。readFromCookiereadFromLocalStoragegetValue 0


以下のコメントを再確認してください。

私が書いたものを読んだことがありますか?何故か出来ないと言っていました。

私はそれを少し見逃しましたが、敬意を表して、できます. コードのリファクタリングが必要になる場合がありますが、実行できますし、実行する必要があります。これが最新の Web アプリケーションの仕組みです。構造がサポートしていない場合は、構造を修正する必要があります。適切に実行できるようになるまで、一時的なasync: false回避策として要求に応じて使用できます。(ねえ、私たちは皆そこにいて、そのようなことをしなければなりませんでした。) 間もなく廃止される予定であることに注意してください (jQuery がサポートしているだけで、XHR を直接使用して同期要求を行うことができます)。


更新された質問について、そのコードを更新する方法は次のとおりです。

MyClass123.prototype.myMethod = function(value) {
  this.getState("key1", function(var1) {
    //                           ^--- Note the var becomes an arg
    if var1 == "123"{ ... }
    else { .... }
  });
};

実際にどれだけ変化するかに注意してください。への呼び出しに従うために使用されるロジックは、getState代わりに、それに渡すコールバックに入ります。

于 2013-01-27T12:36:51.450 に答える
2

async: false-を指定することで、AJAX リクエストを同期させることができますが、これは推奨されませんが可能です。getValue()AJAX リクエストが返される前に関数が返されてはならないことが絶対にある場合は、それasyncが道です。

$.ajax({
    type: "GET",
    url: "123",
    async: false // NEW
    data: { .... },
    success: function(data){
        value = data; 
    }
});

thenとを使用する代替when:

function getValue(key, callback) {
   switch(_options.myType){

     ...

     case "db":
       return $.ajax({ // note the 'return'
           type: "GET",
           url: "123",
           ...
       });
   }
}

そして、あなたがそれを呼び出す場所では、次のように呼び出します:

$.when(getValue()).then(function() {
   // do the rest here ...
});
于 2013-01-27T12:36:12.267 に答える
2

正しいことは、プログラム フローを再構築して、ロジックをハンドラーに配置できるようにすることです。success

オプションを使用して Ajax リクエストを同期させることはできasyncますが、それはばかげています。リクエストが成功する (またはタイムアウトする) までブラウザー ウィンドウがフリーズするため、アプリの速度が低下します。JavaScript 開発ではあまり使用されませんが、それには正当な理由があります。

于 2013-01-27T12:36:27.867 に答える