2017-06-23 23 views
1


我想調用Ajax請求3倍順序(請求有相同的URL),其描述:
Request 1 -> Done -> Request 2 -> Done -> Request 3 -> Done -> Do something如何使用jquery循環我的ajax請求?

在各回調函數,如果有任何條件是正確的,則環將端。 我可以寫簡單的腳本來執行,如:

$.ajax().then(function() { 
    if (condition) {} 
    else { 
     $.ajax().then(function() { 
      if() else() { 
       $.ajax().then(function() { 
        if() else(); 
       }); 
      } 
     }); 
    } 
}); 

但是,如果它不是隻有3次(前n次),這樣看上去那麼愚蠢。
我如何使用Promise發出很多請求?
非常感謝!

+0

有沒有更好的解決方案? –

回答

2

經典JavaScript問題。

您可以使用產量關鍵字查看「生成器」。

這是EcmaScript 6中的一項新功能,它使異步調用看起來/感覺同步。

這正是避免了你偶然發現的「Ajax Christmas-tree」,而不會破壞你的調用的異步性質。

現在他們可能看起來有點錯綜複雜。但一旦你進入它,它應該成爲第二天性。想象一下,再也不用處理$ .ajax事件的遞歸網絡。

注意:我自己還沒有完全理解它們。但是到目前爲止,在我的實驗中,我獲得了您在下面看到的代碼。我想你最終必須通過傳遞生成器來調用包裝。如果其他人能夠更多地瞭解這一點,將不勝感激。

下面是一個例子:

<script> 

    // -- I: Basic Example 

    function generator() 
    { 
     yield 0 + 1; 
     yield 0 + 2; 
     yield 0 + 3; 
     yield "Hello"; 
     return "Done."; 
    } 

    var gen = generator(); 

    // Iterate through return values until done 

    gen.next(); // 1 
    gen.next(); // 2 
    gen.next(); // 3 
    gen.next(); // "Hello." 
    gen.next(); // "Done." 


    // -- II: Take this principle to a real-case scenario: 

    window.onload = function() { 

     // Generator - asynchronous code that looks synchronous 
     function generator() { 
      var tweets = yield $.getJSON("data/tweets.json"); 
      var friends = yield $.getJSON("data/friends.json"); 
      var followers = yield $.getJSON("data/followers.json"); 
     } 

     // Wrap 
     function wrapper(generator) { 
      var gen = generator(); 

      // Handle 
      function handle(yielded) { 
       if (!yielded.done) { 

        // Then 
        yielded.value.then(function(data) { 

         // Next 
         return handle(gen.next(data)); 
        }); 
       } 
      } 
     } 
    } 
</script> 
+0

感謝您的回答。它很清楚。但是我現在有截止日期,所以@ user2864740的編碼方式比較容易。我會盡快測試你的解決方案。再次感謝! –

3

使用香草承諾,一個 「遞歸函數」 是可行的。只需提供每次遞歸調用的次數(加1)。如果有額外的工作要做,遞歸函數本身會返回一個新的承諾。

var maxCalls = 3 

function makeCall(timesCalled) { 
    // we're done - don't return a chained promise 
    if (timesCalled > maxCalls) 
    return; 

    return $.ajax().then(function() { 
     // likewise - don't return chained promise 
     // (it may make sense to move this up outside) 
     if (condition) 
     return; 

     // return the next promise, or not if done 
     return makeCall(timesCalled + 1); 
    }); 
} 

var promiseResolvedAtEnd = makeCall(1); 
+1

它爲我工作。非常感謝。 –