2011-12-26 12 views
1

チェーン内の別個の操作を完了するコードがあります。一連の操作は、ループ内で実行されます。私が扱っているシステムの性質上、操作セットは同期して実行される必要があります(つまり、最初のセットが終了する前に次の操作セットは実行できません)。非同期実行は、リモートプロセッサを(私の制御ではなく)捨てて、コードが失敗する原因になります。今、私がこれを動作させるための唯一の方法は、アラートボックスを使用することです。これは本当に不自由でオプションではありません。私が試した:前のセットが完了した後でのみ、ループ内で一連の作業を実行します。

  • $アヤックスを使用して、スリープ機能に(絶望で使用)
  • 警告ボックスここ

がコードであるを使用して偽
  • に非同期の設定します - 任意の考え?:

    $('input:checked').each(function(index){       
    
        //get the item's location id 
        var currentInput = $(this).val(); 
    
        var copyUser = function(){$.get(urlCopyPrefix + currentInput + urlSuffix);} 
        var moveUser = function(){$.get(urlMovePrefix + moveLocation + urlSuffix);} 
    
        var cleanup = function(){ 
    
         var newSibling = $('#module-' + moveLocation); 
         newSibling.before('<li>New Line</li>'); 
    
         alert('done'); 
        } 
    
        /* --> THIS IS THE CODE IN QUESTION <-- */ 
        $.when(copyUser()).pipe(moveUser).then(cleanup); 
    
    }); 
    
  • 答えて

    1

    私はそれがすぐに全体の反復を実行しますので、あなたが.each()の使用を停止しなければならないと思いますそれをしたくないです。

    ここで補完機能とローカル機能を使用して、それを行うための一つの方法です:

    function copyMove(moveLocation, urlCopyPrefix, urlMovePrefix, urlSuffix) 
        var checked = $('input:checked'); 
        var index = 0; 
    
        function next() { 
         if (index < checked.length) { 
          var currentInput = checked.eq(index++).val(); 
          $.get(urlCopyPrefix + currentInput + urlSuffix, function() { 
           $.get(urlMovePrefix + moveLocation + urlSuffix, function() { 
            $('#module-' + moveLocation).before('<li>New Line</li>'); 
            next(); 
           }); 
          }); 
         } 
        } 
    
        next(); 
    } 
    

    か、のDeferredを使用して:

    あなたのDeferredに
    function copyMove(moveLocation, urlCopyPrefix, urlMovePrefix, urlSuffix) 
        var checked = $('input:checked'); 
        var index = 0; 
    
        function copyUser() { 
         var currentInput = checked.eq(index).val(); 
         return $.get(urlCopyPrefix + currentInput + urlSuffix); 
        } 
        function moveUser() { 
         return $.get(urlMovePrefix + moveLocation + urlSuffix); 
        } 
        function cleanup() { 
         ++index; 
         $('#module-' + moveLocation).before('<li>New Line</li>'); 
         next(); 
        } 
    
        function next() { 
         if (index < checked.length) { 
          $.when(copyUser()).pipe(moveUser).then(cleanup); 
         } 
        } 
    
        next(); 
    } 
    

    注:関数の参照を渡す必要があります関数呼び出しではありません。つまり、括弧を付けずに関数名を渡すことになります。

    +0

    私は頼む異なる。 'copyUser'と' moveUser'はDeferreds自身ではありません。いったん呼び出されると、彼らはDeferredを返します。 'when' /' then'が動作する唯一の方法は、あなたが関数を呼び出して、返されたDeferredを 'when' /' then'に渡すことです。 –

    +0

    また、彼は絶対に 'pipe'メソッドを使用しなければなりません。あなたが 'then'関数を追加しているだけなら、彼らはお互いを待つことはありません。 OPは明確に 'cleanup'を実行する前に' moveUser'が復帰することを明確に望んでいます。それを達成する唯一の方法は 'pipe'です。 –

    +1

    OK、 'pipe()'に戻りました。パイプ上のjQueryのドキュメントは価値がありません。 – jfriend00

    1

    あなたの関数からjqXHRオブジェクトを返すことがあります。

    var copyUser = function(){ 
         return $.get(urlCopyPrefix + currentInput + urlSuffix); 
        }, 
        moveUser = function(){ 
         return $.get(urlMovePrefix + moveLocation + urlSuffix); 
        }; 
    

    次に、あなたが行うことができます:

    $.when(copyUser()).pipe(moveUser).then(cleanup); 
    

    をあなたがするループ内の各項目を待ちたい場合次のものが始まる前に行ってください:

    var $items = $('input:checked'), 
        length = $items.length, 
        copyUser = function(currentInput) 
        { 
         return $.get(urlCopyPrefix + currentInput + urlSuffix); 
        }, 
        moveUser = function() 
        { 
         return $.get(urlMovePrefix + moveLocation + urlSuffix); 
        }, 
        cleanup = function() 
        { 
         $('#module-' + moveLocation).before('<li>New Line</li>'); 
        }; 
    
    function processUser(i) 
    { 
        $.when(copyUser($items.eq(i).val())).pipe(moveUser).then(function() 
        { 
         cleanup(); 
         i < length && processUser(++i); 
        }); 
    } 
    
    processUser(0); 
    
    +0

    しかし、これはまだすべての 'copyUser()'関数を起動しません.each()ループは何も待たずに完了するだけです。 – jfriend00

    +0

    はい、そうです。私はOPがループを非同期で実行することに気づいていなかった。私の答えは1分後に更新されます。 –

    +0

    この行は '$ .when(copyUser($ items.eq(i).val())).pipe(moveUser())' 'copyUser()'と 'moveUser()'を直ちに呼びますか?それらの戻り値を '$ .when()'と '.pipe()'メソッドに渡します。私はそれがOPが望んでいるとは思わない。これはajax呼び出しをシーケンスしません。 – jfriend00

    関連する問題