在Javascript中的for循环中运行不同的api

Running a different api in a for loop in Javascript

本文关键字:api 运行 Javascript 中的 for 循环      更新时间:2023-12-03

我的目标是为列表中的各种艺术家记录所有这些API。API的问题是,每个艺术家都有自己的API,因此必须多次调用,每个艺术家调用一次。

var artistList = [...]; //let's say there is a hypothetical 100 artists
var n = artistList.length; //this would be 100
for (var i=0; i<n; i++) {
    var request = new XMLHttpRequest();
    var urlApi = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=' + artistList[i] + '&api_key=somApiKeyThatWorks&format=json';
    console.log(urlApi);
    request.open('GET', urling, true);
    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        var data = JSON.parse(request.responseText);
        console.log(data);
      } else {
      }
    };
    request.onerror = function() {
    };
    request.send();
};

现在,当我运行这个并检查控制台时,只有最后列出的项目显示数据。因此,我记录了所有这些API,并在每个API中正确地使用相应的艺术家,但我只记录了一个JSON。

如果有人能告诉我如何获得它,以便为每个API记录每个JSON,那就太好了。我有一种感觉,这是因为request.responseText需要一段时间,所以它在完成之前跳过它,导致它只记录列表中的最后一个项目。不知道如何处理。我也不能使用jQuery,因为有人明确要求我不要使用jQuery。

问题很简单:request是非阻塞的,所以当调用request.send()时,它会让for循环完成。但是,当for循环开始下一次迭代时,request将被覆盖,因此只记录最后一个请求。

有两种方法可以解决这个问题:

  • request中的true更改为false。这将它从非阻塞更改为阻塞,并将暂停循环,直到请求完成并得到响应。然后你就可以保证它会起作用。

  • 使用map收集您的结果。即调用artistList.map(makeRequest),其中makeRequest使用来自artistList的艺术家作为输入返回XMLHTTPRequest的结果。

    (我不保证这会起作用!如果不起作用,请四处寻找类似于在数组上操作的异步请求的东西,或者使用第一种方法。)

您应该在for循环之前声明一个对象。并附加其中的所有记录。

示例:

        var artistList = [...]; //let's say there is a hypothetical 100 artists
        var n = artistList.length; //this would be 100

var结果={};

        for (var i=0; i<n; i++) {
            var request = new XMLHttpRequest();
            var urlApi = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=' + artistList[i] + '&api_key=somApiKeyThatWorks&format=json';
            console.log(urlApi);
            request.open('GET', urling, true);
            request.onload = function() {
              if (request.status >= 200 && request.status < 400) {
                var data = JSON.parse(request.responseText);
                console.log(data);

results[artistList[i]]=数据;

              } else {
              }
            };
        request.onerror = function() {
        };
        request.send();
    };

现在,您已经在results对象中拥有了所有数据。

希望它对你有用。

这就是臭名昭著的循环问题(滚动到The Infamous Loop Problem is discussed所在的内容)这是处理函数循环时必须知道的问题。要使其工作,请使用以下语法。

request.onload = function(thisRequest) { // this is the current request and now inside this block it will refer to the same request object.
  return function(){
    if (thisRequest.status >= 200 && thisRequest.status < 400) {
     var data = JSON.parse(thisRequest.responseText);
     console.log(data);
    }
    else {
    }
  }
}(request);  //pass the current request as the parameter to this function and execute

在这里解释问题,

每个循环的请求变量都会发生变化,由于onload函数没有执行,只是应用了它,因此请求变量会一直变化,直到循环结束。因此,当for循环退出时,request的最后一个值将应用于所有函数。

为了克服这个问题,我们必须在每个循环中执行函数,将循环的当前请求对象作为参数传递。现在,在这个函数范围内,请求变量将始终是作为参数传递的变量。