如何制作一个干净的异步循环

How to make a clean Asynchronous loop?

本文关键字:异步 循环 一个 何制作      更新时间:2023-09-26

遵循典型的REST标准,我将资源分解为单独的端点和调用。这里讨论的主要两个对象是ListItem(当然,列表有一个项目列表,以及与之相关的其他一些数据)。

因此,如果用户想检索他的列表,他可能会向api/Lists 发出Get请求

然后,用户可能想要获取其中一个列表中的项目,并进行get to api/ListItems/4,其中4是从上次调用中检索到的List.listId中找到的。

这一切都很好:$.ajaxoptions.complete属性让我可以指向一个回调方法,这样我就可以简化这两个事件。

但是,如果我想获得所有有问题列表的元素,事情会变得非常混乱。例如,让我们假设我有一个名为makeGetRequest的库函数,它接受端点和回调函数,以使代码更干净。简单地检索3个元素,天真的方式会导致以下结果:

var success1 = function(elements){
    var success2 = function(elements){
       makeGetRequest("api/ListItems/3", finalSuccess);
    }
    makeGetRequest("api/ListItems/2", success2);
}
makeGetRequest("api/ListItems/1", success1);

恶心这是在编程101中我们被拍手腕并指向循环的那种事情。但是,在不依赖外部存储的情况下,如何使用循环来实现这一点呢?

for(var i : values){
    makeGetRequest("api/ListItems/" + i, successFunction);
}
function successFunction(items){
    //I am called i-many times, each time only having ONE list's worth of items!
}

即使有了存储,我也必须知道所有何时完成并检索到它们的数据,并调用一些主函数来检索所有收集到的数据并对其进行处理。

有处理这个问题的方法吗?这个问题以前一定解决过很多次。。。

尝试使用一组端点参数:

var params = [];
var results [];
params.push({endpoint: "api/ListItems/1"});
params.push({endpoint: "api/ListItems/2"});
params.push({endpoint: "api/ListItems/3"});
params.push({endpoint: "api/ListItems/4"});

然后你可以在你的成功处理程序中递归:

function getResources(endPoint) {
   var options = {} // Ajax Options
   options.success = function (data) {
       if (params.length > 0) {
           results.push({endpoint: endpoint, data: data});
           getResources(params.shift().endpoint);
       }
       else {
          theMasterFunction(results)
       }
   }
   $.get(endPoint, options)
}

你可以从这样的一个电话开始:

getResources(params.shift().endpoint);

编辑:

为了使所有内容都保持独立并脱离全局范围,您可以使用一个函数并提供回调:

function downloadResources(callback) {
    var endpoints = [];
    var results [];
    endpoints.push({endpoint: "api/ListItems/1"});
    endpoints.push({endpoint: "api/ListItems/2"});
    endpoints.push({endpoint: "api/ListItems/3"});
    endpoints.push({endpoint: "api/ListItems/4"});
    function getResources(endPoint) {
        var options = {} // Ajax Options
        options.success = function (data) {
           if (endpoints.length > 0) {
               results.push({endpoint: endpoint, data: data});
               getResources(endpoints.shift().endpoint);
           }
           else {
              callback(results)
           }
        }
       $.get(endPoint, options)
    }
    getResources(endpoints.shift().endpoint);
}

使用中:

downloadResources(function(data) {
   // Do stuff with your data set
});

dmck的答案可能是您的最佳选择。然而,另一个选项是执行批量列表选项,以便您的api支持像api/ListItems/?这样的请求?id=1&id=2&id=3.

如果更符合你的个人审美观,你也可以做一个api搜索端点。