2016-07-23 20 views
1

私は特定のサーバーレスポンス(nullでない)を受け取るまでjqueryで遅延ajaxリクエストを行いたいと思います。それをどうやってやりますか?whileループでの遅延

while (data.response != null) { 
    $.ajax(..).done(function(data); 
} 

function doUntilResult() { 
    Server.doA().done(function(data) { 
     Server.doB(data).done(function(result) { 
      //if result == null, repeat again 
     }); 
    }); 
} 

答えて

0

受け入れるようにdoUntilResult()を書き、コントロールの大規模な措置を与える:

  • どう処理するかを決定するdoThisコールバック関数、および再試行/終了条件を。
  • 整数は、呼び出し間の遅延を決定します。
    function doUntilResult(doThis, t) { 
        function delay() { 
         return $.Deferred(function(dfrd) { 
          window.setTimeout(dfrd.resolve, t); 
         }); 
        } 
        function poll() { 
         return $.when(doThis()).then(function(data) { // $.when() caters for non-async functions to be passed. 
          return (data === null) ? delay().then(poll) : data; // continue on null, otherwise return data. 
         }); 
        } 
        return poll(); 
    } 
    

は今、あなたはそれが可能、再書き込みなし「になるまでに行われる」とは何かについてのあなたの心を変更すること、一般 doUntilResult()機能を持っています。すべてがコール(またはコール)で指定されています。元の質問については

、次のように呼び出します。編集した質問については

doUntilResult(function() { 
    return $.ajax(..).then(function(data) { 
     return data || null; // adjust as required to ensure that `null` is returned only for the "continue" condition. 
    }); 
}, 1000); // 1 second delay between calls 

を、次のように呼び出します。

doUntilResult(function() { 
    return Server.doA().then(function(data) { 
     return Server.doB(data); 
    }).then(function(result) { 
     return result || null; // adjust as required ... 
    }); 
}, 1000); // 1 second delay between calls 

あなたがやりたいものは何でも、常にそのコールバックの.thenチェーンを確保ポーリングを継続するたびにnullを返す関数で終了します。

Here's a simple demo 0-10から乱数を生成します。 9以上の数字はデータとして扱われます。 9歳未満で再試行されます。(コンソールで進行状況を監視する)。

1

Javascriptでこのようにループすることはできません。 Javascriptはイベント駆動型のシステムです。このようにループすると、他のイベントは処理されません。したがって、最初のAjax呼び出しでさえ処理されません。事実、クライアントが何百万ものAjaxコールを一斉に呼び出そうとすると、リソースを使い切ってJSエンジンを地面に追いやるだけです。

代わりに、あなたは非同期Ajaxの結果を使用して、再びそれを呼び出すかどうかの結果から判断することができます。

function poll() { 
    $.ajax(...).then(function(data) { 
     if (!data.xxxx) { 
      // call it again after some short delay 
      setTimeout(poll, 1000); 
     } else { 
      // got the result we wanted, process it 
     } 
    }) 
} 

// start the polling 
poll(); 

あなたは全部が約束を返すようにしたい場合は、あなたがこれを行うことができます:

function delay(t) { 
    return new $.Deferred(function(def) { 
     setTimeout(def.resolve, t); 
    }).promise(); 
} 

function poll() { 
    return $.ajax(...).then(function(data) { 
     if (!data.xxxx) { 
      // call it again after some short delay 
      return delay(1000).then(poll); 
     } else { 
      // got the result we wanted, process it 
      return someValue; 
     } 
    }) 
} 

// start the polling 
poll().then(function(result) { 
    // process result here 
}); 

PSできるだけ速くサーバーを常にポーリングするのは正しいことではありません。何人かのユーザーしかいない場合でもうまくいくかもしれませんが、多くのユーザーがいるとすぐに、空のポーリング要求でサーバーを圧倒します。ほとんどの場合、クライアントには何も返されません。これは負荷を処理するための悪夢です。ポーリングしていないアーキテクチャを見つける方が良いですが、ポーリングする場合は、できるだけ早くではなく、ある種のタイマーを使用して将来の時間にポーリングしてください。

P.P.S.サーバー上で値を変更するのを待っているのであれば、おそらくwebSocket接続を使用する必要があります。これにより、クライアントはサーバーとの接続を確立し、接続は維持された後、将来、サーバーは単にクライアントにメッセージを送信することができます。クライアントはまったくポーリングする必要はありません。これは、サーバーインフラストラクチャ上で大幅に効率化され、よりタイムリーな結果を提供できます。

+0

この投票で延期を使用したいと思いますが、それは可能ですか?私がpoll()を行うことができるようにdone(...)もちろん、data.xxx? – Wesley

+0

@ウェズリー - あなたが望むものは分かりません。すでに約束を使っている私の答えに '$ .ajax(...)。then()'があります。私は、jQuery固有の '.done() 'ではなく、ES6標準の' .then() 'を使用することを好みます。ポーリングが完了したときにすべてが約束を返すようにしたい場合は、それを行うことができます(それはあなたがあなたの質問で尋ねたものではありません)。 – jfriend00

+0

@Wesley - もう1つのオプションを追加しました。 – jfriend00

関連する問題