2016-12-08 10 views
4

JavaScriptで遅延クラスを初めて使用し、フォームをループして1つずつ送信する関数を実装したいと考えています。jQueryを使用した遅延非同期タスク

これは、遅延クラスのように見えます。

私はthis answerに従ってみましたが、何らかの理由で私の実装が始まり、3秒待って完了します。すべてのフォームが完了してから完了するまで、3秒ごとに別のフォーム名を表示します。

私は間違っていますか? JSFIDDLE

function syncAll() { 
 
     
 
    var promises = []; 
 
    var forms = [ 
 
    {'name':'form 1'}, 
 
    {'name':'form 2'}, 
 
    {'name':'form 3'}, 
 
    {'name':'form 4'}]; 
 

 
    $.each(forms, function (index, value) { 
 
    var def = new $.Deferred(); 
 
    setTimeout(function() { 
 
     $("#output").html("Syncing: " + value.name); 
 
     def.resolve({ 'message': 'finito!' }); 
 
    }, 3000); 
 
    promises.push(def); 
 

 
    }); 
 

 
    return $.when.apply(undefined, promises).promise(); 
 
} 
 
    
 
    
 
    $.when(syncAll()).done(function(response){ 
 
     $("#output").html(response.message); 
 
    }); 
 
    /* 
 
    syncAll().done(function (response) { 
 
     $("#output").html(response.message); 
 
    })); 
 
    */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="output">Start</div>

+2

'$ .when'は、約束*をパラレル*に適用し、それらがすべて終了するのを待ちます。すべてのフォームが同時に提出されています。 * .then()でシーケンスを*連鎖したい –

+0

あなたのコードをきれいにするのに便利です。 –

+0

@GoneCoding - 同じ関数を呼び出すループの場合、シーケンスをどのようにチェーンするのですか? 'submitForm'と言ってください。 – capdragon

答えて

5

JSFiddle:これはのsetTimeoutを交換し、時限約束方法を有することによってビットを向上させることができ

function syncAll() { 
    var promise = $.when(); // Start with a resolved promise. 
    var forms = [ 
     {'name':'form 1'}, 
     {'name':'form 2'}, 
     {'name':'form 3'}, 
     {'name':'form 4'}]; 

    $.each(forms, function (index, value) { 
     promise = promise.then(function(){ 
      var def = $.Deferred(); 
      setTimeout(function() { 
       $("#output").html("Syncing: " + value.name); 
       def.resolve({ 'message': 'finito!' }); 
      }, 3000); 
      return def.promise(); 
     }); 
    }); 
    return promise; 
} 


$.when(syncAll()).done(function(response){ 
    $("#output").html(response.message); 
}); 

:これは、promise = promise.then(functionReturningNextPromise)パターンを使用https://jsfiddle.net/TrueBlueAussie/v6cgak1u/2/

その代わりにチェーンも一緒に使用します( setTimeout)。

function syncAll() { 
    var forms = [ 
     {'name':'form 1'}, 
     {'name':'form 2'}, 
     {'name':'form 3'}, 
     {'name':'form 4'} 
    ]; 
    return forms.reduce(function(promise, value) { 
     return promise.then(function() { 
      return $("#output").delay(1000).html("Syncing: " + value.name).promise(); 
     }); 
    }, $.when()).then(function() { 
     return {'message': 'finito!'}; 
    }); 
} 

syncAll().then(function(response) { 
    $("#output").html(response.message); 
}); 

は、これは本質的である:JavaScriptとjQueryのコードはもう少し簡潔にするために活用することができるの

特長:new$.Deferred()

EDIT上で必要とされていないことを

注意上記と同じパラダイムですが、利用する:

  • 'array.reduce()'forms配列から約束を構築する。
  • 遅延を実装するために、setTimeout()の代わりにjQueryの.delay()
+0

優秀ありがとう、私はこれを吸収するためにしばらく時間がかかるし、戻ってあなたの答えを正しいとマークします。天才。 – capdragon

+0

@capdragonでは、javascriptとjQuery ** [like this](https://jsfiddle.net/u75guwv3/)**の機能を悪用して、同じ目的を達成することができます。 –

+0

@ Roamer-1888:詳細な説明で答えとして投稿することをお勧めします。説明するのが複雑すぎるため、自分の例をさらに短縮しませんでした。 –

関連する問題