我不确定这是否是使用ajax的有效方法,但我使用for循环遍历一系列信息:
loadProfiles.js
var tempString = "";
var searchPeople = function(sv){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(xhttp.readyState == 4 && xhttp.status == 200){
tempString = xhttp.responseText;
loadPeople(tempString, sv);
}
}
var searchvalue = sv;
searchvalue = searchvalue.join(" ");
xhttp.open("GET", "php/searchProfiles.php?searchvalue=" + searchvalue, true);
xhttp.send();
}
var loadPeople = function(people, sv){
loadedPeople = [];
var normList = people.split(",");
var list = people.toLowerCase().split(",");
list.splice(list.length - 1, 1);
var zsearch = sv;
for(var i = 0; i < list.length; i++){
loadedImageId[i] = list[i].split("_")[1];
if(loadedImageId[i] == 0){
loadedImageId[i] = "images/GrayProfilePic.png";
}
else{///////////////////////////////////This is what I need to fix
var grabPic = new XMLHttpRequest();
grabPic.onreadystatechange = function(){
if(grabPic.readyState == 4 && grabPic.status == 200){
console.log("ready to go");
loadedImageId[i] = grabPic.responseText;
if(loadedImageId[i] == "Error1"){
loadedImageId[i] = "images/GrayProfilePic.png";
}
}
}
grabPic.open("GET", "php/grabProfPics.php?imageid=" + loadedImageId[i], true);
grabPic.send();
}//////////////////////////////////////////////
list[i] = list[i].split("_")[0];
for(var j = 0; j < zsearch.length; j++){
if(list[i].indexOf(zsearch[j]) > -1){
if(loadedPeople.indexOf(list[i]) == -1){
if(loadedPeople.indexOf(normList[i].split("_")[0]) == -1){
loadedPeople.push(normList[i].split("_")[0]);
}
}
}
}
}
console.log(loadedPeople);
console.log(loadedImageId);
}
searchProfiles.php
$query = "SELECT username, imageid FROM `memberHandler`";
$result = mysqli_query($connect, $query) or die("Could not query");
while($row = mysqli_fetch_assoc($result)){
echo $row['username'] . "_" . $row['imageid'] . ",";
}
grabProfPics.php
$query = "SELECT image, mime_type FROM memberProfilePictures WHERE `id`='$imageid'";
$result = mysqli_query($connect, $query);
if(mysqli_num_rows($result) != 0){
$row = mysqli_fetch_assoc($result);
$imagesrc = $row['image'];
$imagesrc = base64_encode($imagesrc);
$imagetype = $row['mime_type'];
echo "data:" . $imagetype . ";base64," . $imagesrc . "";
}
else{
echo "Error1";
}
然而,服务器需要花费一些时间来发送它的返回码,此时for循环中的变量i早已被改变。有没有办法有效地执行此操作并根据当前数组值的新信息更新数组?我希望这个问题有道理!谢谢你的帮助=)
基本上我试图遍历图片ID,如果id不是零(意味着他们已经为他们的个人资料设置了图片 - 否则他们没有&#39; t并且id为0)那么它将使用ajax连接到图像数据库,获取相对于特定ID的图像,然后返回图像源以及更新数组。对不起,我之前没有更具体的说这个,我只是觉得我可以使用更简化的版本。
答案 0 :(得分:1)
正如你所说的那样,你会抛出一些错误
information[i]
没有doAjaxstuff
方法。但是,我认为你正在尝试的东西很容易用现代浏览器中的原生Promise来完成,甚至jquery 3.0也有兼容的实现。在这种情况下,您可以执行以下操作:
var promises = information.map(function(piece, index) {
//doAjaxstuff must should return a promise
return Promise.resolve([index, doAjaxstuff(piece)]);
});
var inOrderPromises = promises.reduce(function(state, value) {
return state[value[0], value[1]];
}, []);
});
Promises.all(inOrderPromises)
.then(function(inOrderValues) {
//doYourThing
});
答案 1 :(得分:1)
发布问题更新:我在您粘贴所有代码之前写了这个。它仍然适用,但还有一些想法:
new XMLHttpRequest();
代码(而不是使用库,比如fetch或jquery),你应该将它包装在一个函数中(url,data,method,successCb,errorCb)。图书馆会有所帮助。 i
早已继续前进,并且与该调用所用的索引不匹配。
loadedImageId[i] = grabPic.responseText;
继续,原始的aysnc解释:
您正在探讨如何处理一般异步任务,包括ajax调用。
有许多方法可以解决此问题,尤其是callbacks和promises。
虽然你可以以同步的方式做到这一点,但对于除玩具或快速黑客之外的任何事情,最好支持异步数据。
首先,定义我们的服务。在这种情况下,它不会离开我们的机器,但原理是相同的。你发送一些东西(个人资料ID)并得到一些东西(个人资料图片网址)。
// After ~1-2 seconds, answer the callback with the evenness of the input
var isEvenAjax = function(num,cb) {
setTimeout(function(){
var isEven = num % 2 === 0;
cb(num + " is " + (isEven ? "Even" : "Odd"));
},(Math.floor(Math.random() * 12) + 3) * 150);
};
你可以有不同的签名,但这是关键。你将数据放入某个东西,等待一段时间,然后得到回复。
例如:
isEvenAjax(2,console.log);
isEvenAjax(3,console.log);
isEvenAjax(7,console.log);
可能会产生以下反馈:
"7 is Odd"
"2 is Even"
"3 is Odd"
我们的测试数据:
var information = [
10,11,12,
];
现在将我们的数据发送到服务并获得回报。一个简单的foreach可以处理这个问题(注意:这只是为了简单的演示目的。这可能真的很快就会变得非常混乱。承诺是一个很好的方法)。
var getInformationResponses = function(information,cb) {
var responses = [];
information.forEach(function(i){
isEvenAjax(i,function(response){
console.log("Feedback for " + i + " is: " + response);
responses.push({num:i,response:response});
if (responses.length >= information.length){
cb(responses);
}
});
});
};
请注意,包装所有异步调用的函数本身是异步的(并且在我们的回调样式下,它需要完成&#39;回调)。
打破这个局面:
在声明一个响应数组(我们将所有结果放入其中)之后,循环遍历所有信息元素:
var responses = [];
information.forEach(function(i){
对于每个元素,进行异步调用。
isEvenAjax(i,function(response){
对于每个元素的回调(如从长时间运行的服务返回数据时),请注意console.log(用于演示)并将结果和推送到响应数组。维护源数据可能对所有应用程序无关紧要,但在某些情况下(如哪些配置文件ID对应于哪个配置文件URL)它将会。回想一下:异步调用永远不会保证顺序。
console.log("Feedback for " + i + " is: " + response);
responses.push({num:i,response:response});
现在,检查响应数是否与请求匹配。如果没有,那么并非所有结果都在,并且什么都不做。如果是,则触发主回调并将完整数据发送回主调用者。
if (responses.length >= information.length){
cb(responses);
}
这样的例子如下:
getInformationResponses(information,console.log);
可以返回如下内容:
"Feedback for 10 is: 10 is Even"
"Feedback for 12 is: 12 is Even"
"Feedback for 11 is: 11 is Odd"
[[object Object] {
num: 10,
response: "10 is Even"
}, [object Object] {
num: 12,
response: "12 is Even"
}, [object Object] {
num: 11,
response: "11 is Odd"
}]
本练习纯粹是为了探索如何处理异步调用,并且在生产中不能很好地完成。错误处理(ajax调用 失败)等问题不在此处解决。
如CallMeNorm所述,promises可能很棒。我现在没有时间报道他们。
答案 2 :(得分:-1)
Ajax调用是异步的,这意味着他们不会等待for循环完成。如果你想“暂停”迭代并且只在ajax调用返回时恢复,你必须将它设置为同步。
您可以通过添加async: false
了解更多信息,请查看jquery docs