2017-06-15 18 views
2

jQuery Deferredオブジェクトを返す関数がいくつかあります。連鎖して結果を処理するのが難しいです。このすべてで、その結果に何かをし、その後、それらの結果で何かをし、その後test(99)を実行し、test(42)を実行するためにを想定している遅延オブジェクトを返す連鎖関数

const start = Date.now(); 
 

 
// Print a message with a timestamp. 
 
function log (v) { 
 
    console.log(`${Date.now() - start} ${v}`); 
 
} 
 

 
// Return a deferred function that resolves 1 second later with 'value'. 
 
function test (value) { 
 
    log(`test(${value})`); 
 
    return $.Deferred(function (def) { 
 
     window.setTimeout(function() { 
 
      log(`resolve(${value})`); 
 
      def.resolve(value); 
 
     }, 1000); 
 
    }); 
 
} 
 

 
// Example: 
 
test(42) 
 
    .then(function (v) { log(v); }) 
 
    .then(test(99)) 
 
    .then(function (v) { log(v); }) 
 
    .then(function() { log('done'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

は、次の例を考えてみましょう注文。しかし、それは実際に出力する(最初の数は、プログラムが起動してからMSさ):だからtest Sの両方が右の開始時に同時に呼ば

0 test(42) 
0 test(99) 
1003 resolve(42) 
1003 42 
1003 undefined <-- supposed to be 99 
1005 done 
1005 resolve(99) 

取得し、他のすべてがオフになっています。

0 test(42) 
1000 resolve(42) 
1000 42 
1000 test(99) 
2000 resolve(99) 
2000 99 
2000 done 

どのように私はこの作業を行うことができます:私は出力にそれをしたいすることのようなものでしょうか?私は$.Deferred(...).promise()を返してみましたが、動作に変化はなく、thenではなくdoneの代わりにの代わりに42をもう一度印刷しました。

答えて

1

各遅延は1回だけ解決されます。遅延チェーンごとに、それらを正しく接続する必要があります。また、testへの2番目の呼び出しは、すぐに実行されないように関数内にある必要があります。

const start = Date.now(); 
 

 
// Print a message with a timestamp. 
 
function log (v) { 
 
    console.log(`${Date.now() - start} ${v}`); 
 
} 
 

 
// Return a deferred function that resolves 1 second later with 'value'. 
 
function test (value) { 
 
    log(`test(${value})`); 
 
    return $.Deferred(function (def) { 
 
     window.setTimeout(function() { 
 
      log(`resolve(${value})`); 
 
      def.resolve(value); 
 
     }, 1000); 
 
    }); 
 
} 
 

 
// Example: 
 
test(42) 
 
    .then(function (v) { log(v); }) 
 
    .then(function() { 
 
     test(99) 
 
      .then(function (v) { log(v); }) 
 
      .then(function() { log('done'); }); 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

ああ、私は、感謝を参照してください。そして、これを入れ子にするのが唯一の方法です。だから、もし私が、例えば、forループや何かを使って長いチェーンを構築しているなら、それらを順番にやるようなヘルパー関数を書いたり、すべてをこのネストされたフォームにフィネスしなければならないのですか? –

+1

deferredが解決すると、deferredを含むかどうかにかかわらず、then()をすべて実行します。だからあなたはあなたのロジックを念頭に置いてチェーン化しなければなりません。 – Taplar

+0

Btw、私はちょっと試してあなたのアドバイスをしました、実際には*私はちょうど*テスト*への2番目の呼び出しをネストしなくても(その遅延オブジェクトを返す)関数にすると正しく動作するように見えます。 this](https://pastebin.com/r5Eda5Zp)。おそらく、 'then'ハンドラが何かを返すと、それはチェーンの残りの部分の動作を変えますか? –

関連する問題