Jquery Ajax GET调用不同的结果

时间:2017-07-05 12:25:26

标签: javascript jquery ajax

我写了几行代码来解决以下问题:

根据用户名获取TwitchTV用户ID。用户名在arrray中。点击一个按钮后,将调用GET AJAX请求以获取UserID并将其推送到另一个数组中,并在按下按钮后通过AJAX调用API。

我的问题是,如果我再次点击按钮,则userID的顺序错误。

如果我设置async:false,则可以。

这是因为异步AJAX的问题吗?有效修复的方法是什么?使用回调?我们将赞赏正确方向的暗示。

代码中的注释用于测试。

代码:

<script>

        var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
            clientID = "?client_id=XXX";
            userID = [];
            userStatus = [];
for(var i=0; i<users.length; i++){
          idCall(users[i]);

        };
function idCall (data){
            $.ajax({
              type: "GET",
              url: "https://api.twitch.tv/kraken/users/" + data + clientID,
              async: false,
              cache: false,
              dataType: "jsonp",
              success: function (data){
                console.log(data._id);
              }, 
              error: function (data) {
                console.log("error");
              }});
        };
</script>

3 个答案:

答案 0 :(得分:1)

使用一系列请求承诺并在解决所有这些后更新dom。结果将与原始用户数组

的顺序相同
        FileStream stream = File.Open(@"C:\Users\Desktop\ExcelDataReader.xlsx", FileMode.Open, FileAccess.Read);
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        DataSet result = excelReader.AsDataSet();
        excelReader.IsFirstRowAsColumnNames = true;         
        DataTable dt = result.Tables[0];
        string text = dt.Rows[1][0].ToString();

答案 1 :(得分:0)

  

有效修复的方法是什么?

我认为@charlieftl answer is a good one。我不认为我能真正改善这一点。我主要是在这里尝试解释你的困难。正如我在上一个问题中提到的那样,您需要阅读并理解How do I return the response from an asynchronous call?

如果您拥有对服务器端的控制权,那么更简单的选择是按顺序发送阵列服务器端并使用它来维护订单,但是您使用的是第三方API,因此这并不实用。< / p>

更简单的选择是使用回调方法:

 var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
 var clientID = "?client_id=XXX";
 var userID = [];
 var userStatus = [];
 idCall(users);


 function idCall (users, x=0){
        if (x < users.length)
        {
            var data = users[x];
            $.ajax({
              type: "GET",
              url: "https://api.twitch.tv/kraken/users/" + data+ clientID,
              cache: false,
              dataType: "jsonp",
              success: function (data){
                console.log(data._id);
              }, 
              error: function (data) {
                console.log("error");
              }})
              .then(function(){
                  idCall(users, x++);
              });
          }
    };
虽然像我说的那样,但是查理的答案更好。这将保证订单并且不会锁定UI。但它很慢。

  

这是因为异步AJAX的问题吗?

是的,在服务器和订购上进行异步处理。

当您第一次打开调试工具的network panel并观看HTTP请求时。你会看到的是一大堆请求同时被发送但以不同的顺序返回。您无法保证异步请求的响应顺序。这取决于服务器响应时间,负载等。

实施例: enter image description here

我们按照A,B,C,D,E,F,G的顺序发送这些请求,但我们在B,C,E,F,G,D,A中收到的回复是你问题的核心。

async设为false即可:

enter image description here

现在没有请求将被发送,直到上一次返回,但是。所以东西被发送AG并返回AG,但这比前一个例子 A LOT 慢(这里的图表没有按比例缩放,我努力捕获一个好的async:false示例我从不使用它,见下面的原因)。

从不这样做(几乎所有)。会发生什么情况是UI线程将被锁定(Javascript/browsers are single threaded, mostly)等待外部呼叫,并且您的网站将在很长一段时间内无响应。锁定此线程并不会停止Javascript,它会停止整个站点,因此链接不起作用,将鼠标悬停在所有内容上,直到异步调用将线程返回到UI。

答案 2 :(得分:-1)

是的,这是因为AJAX调用。一个AJAX调用可能在另一个之前完成,因此顺序不同。

一个显而易见的解决方案是使用jQuery promises但是这个问题的另一个解决方案可能是你在AJAX调用完成后对数组进行排序。

您可以根据用户名字符串对数组进行排序,如下所示:

data.sort();

如果你有一组对象,你不在示例代码中,你可以这样排序:

data.sort(function (a, b) { return (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0); } );

在完成评论后,我想提供更多代码,以便更好地了解如何解决这个问题。

<script>

var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
clientID = "?client_id=XXX";
userID = [];
userStatus = [];

var count = 0;
for(var i=0; i<users.length; i++){
    idCall(users[i]);
}

function idCall (data){
   $.ajax({
        type: "GET",
        url: "https://api.twitch.tv/kraken/users/" + data + clientID,
        async: false,
        cache: false,
        dataType: "jsonp",
        success: function (data){
            console.log(data._id);
            userID.push(data._id);
            count++;
            if( count === users.length - 1 ) {
                userID.sort();
            }
        }, 
        error: function (data) {
            console.log("error");
        }

   });
}