2015-11-12 110 views
0

我正在編寫一個工具,它將通過id列表(由id_list中的id表示)進行循環。我們檢查一個緩存對象,看看我們是否已經有了這個id的值。如果我們還沒有給定id的值,我們需要發出get請求來獲取關聯值,然後將其添加到緩存中。異步獲取請求完成時僅繼續循環

在完成一個async獲取請求所需的時間內,整個循環運行。這意味着緩存永遠不會被實際使用。無論如何,我可以要求get請求在繼續循環之前完成?通常我會通過前面的onSuccess函數連接請求,但由於有變化,不會提出請求。

cache = {}; 
var rating; 
for (id in id_list){ 
    if (id in cache){ 
     rating = cache[id]; 
    }else{ 
     rating = $.get(~~~async get request happens here~~~); 
     cache[id] = rating; 
    } 
    $(".result").append(rating);//display result in ui 
} 

回答

3

如果您希望它在每次迭代之間等待,則不能使用for循環。一個常見的設計模式是爲給定的迭代創建一個本地函數,然後在每次異步操作完成時調用它。

假設id_list與屬性的對象,你可以做這樣的:

var cache = {}; 
var ids = Object.keys(id_list); 
var cntr = 0; 
function next() { 
    var id; 
    if (cntr < ids.length) { 
     id = ids[cntr++]; 
     // see if we can just get the value from the cache 
     if (id in cache) { 
      $(".result").append(cache[id]); 
      // schedule next iteration of the loop 
      setTimeout(next, 1); 
     } else { 
      // otherwise get rating via Ajax call 
      $.get(...).then(function(rating) { 
       $(".result").append(rating); 
       // put rating in the cache 
       cache[id] = rating; 
       next(); 
      }); 
     } 
    } 
} 

next(); 

或者,如果id_list是IDS的數組,你可以把它改成這樣:

var cache = {}; 
var cntr = 0; 
var id_list = [...]; 
function next() { 
    var id; 
    if (cntr < id_list.length) { 
     id = id_list[cntr++]; 
     // see if we can just get the value from the cache 
     if (id in cache) { 
      $(".result").append(cache[id]); 
      // schedule next iteration of the loop 
      setTimeout(next, 1); 
     } else { 
      // otherwise get rating via Ajax call 
      $.get(...).then(function(rating) { 
       $(".result").append(rating); 
       // put rating in the cache 
       cache[id] = rating; 
       next(); 
      }); 
     } 
    } 
} 

next();