2015-11-12 70 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();