仅在异步获取请求完成时继续循环 [英] Only continue for loop when async get request finishes

查看:118
本文介绍了仅在异步获取请求完成时继续循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个将遍历id列表(在id_list中由id表示)的工具.我们检查一个缓存对象,看是否已经有一个id值.如果尚无给定ID的值,则需要发出get请求以获取关联的值,然后将其添加到缓存中.

I am writing a tool that will loop through a list of id's (represented by id in id_list). We check a cache object to see if we already have a value for the id. If we don't already have a value for the given id, we'll need to make a get request to get the associated value and then add it to the cache.

在执行一个async获取请求所需的时间中,整个循环都会运行.这意味着永远不会实际使用缓存.无论如何,在继续循环之前,我是否可以要求get请求完成?通常,我会通过上一个的onSuccess函数将请求链接起来,但是由于有更改,因此不会发出请求.

In the time it takes to do one async get request, the entire loop runs. This means the cache is never actually used. Is there anyway I can require the get request to finish before continuing the loop? Normally I would chain the request through the onSuccess function of the previous, but since there's a change, no request will be made.

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
}

推荐答案

如果希望循环在每次迭代之间等待,则不能使用for循环.一种常见的设计模式是为给定的迭代创建一个局部函数,然后在每次异步操作完成时调用它.

You can't use a for loop if you want it to wait between each iteration. A common design pattern is to create a local function for a given iteration and then call it each time the async operation finishes.

假设id_list是具有属性的对象,则可以这样操作:

Assuming id_list is an object with properties, you could do it like this:

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是ID数组,则可以将其更改为:

Or, if id_list is an array of ids, you can change it to this:

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();

这篇关于仅在异步获取请求完成时继续循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆