我写了几行代码来解决以下问题:
根据用户名获取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>
答案 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请求时。你会看到的是一大堆请求同时被发送但以不同的顺序返回。您无法保证异步请求的响应顺序。这取决于服务器响应时间,负载等。
我们按照A,B,C,D,E,F,G的顺序发送这些请求,但我们在B,C,E,F,G,D,A中收到的回复是你问题的核心。
将async
设为false
即可:
现在没有请求将被发送,直到上一次返回,但是。所以东西被发送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");
}
});
}