我正在使用Google的Feed API构建一种RSS Feed阅读器。经过多次试验和错误,我已经能够通过PHP实例化与给定RSS URL的连接,并返回JSON对象。我遇到的问题是我试图从数组中验证多个URL,但由于AJAX的异步性质以及通过Google API加载时滞,结果代码会在验证完成之前触发。我尝试过这样的事情:强制同步,setTimeouts,.promise调用验证的对象,但是我没有在哪里。任何帮助都会受到极大的赞赏。
我的代码:
PHP
$feed = $_POST['feed'];
$url = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=&q=" . $feed;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, www.mywebsiteurl.com);
$body = curl_exec($ch);
curl_close($ch);
echo $body;
此代码段成功创建与指定Feed网址的连接,并返回包含Feed数据的JSON对象。我用以下的AJAX调用调用这个外部php脚本:
AJAX:
var conn = $.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]}
});
conn.done(function (data){
var err = eval('(' + data + ')' ).responseStatus;
if (err==200){
console.log("Success");
} else if (err==400){
console.log("Failure with: " + err);
}
});
此代码可以完美地用于单个连接尝试,但我需要线性地逐步执行一系列提要,测试提要,等待连接结果,然后继续执行数组中的下一个提要,或者打破成功连接。
我试图为feed_a []使用$ .each语句,但是循环的触发速度比返回的结果要快。我想我需要操作缓冲区,但我不确定如何实现它。
与往常一样,如果需要,我可以根据要求提供额外的代码,之前的尝试或更多的澄清。如果需要,我可以在我的网站上现场托管代码以进行演示。
更直接的问题:如何强制循环($ .each,for循环或递归函数)等待AJAX调用的结果?
此外,为了将来更好地提出问题,有人可以解释为什么我的问题可能会被标记下来吗?
编辑:感谢大家快速回复!以下代码似乎可以解决我的问题:
$.each(v_feed, function(_,url){
$.ajax("php/feedlog.php",{
type: "POST",
data: { feed: url }
}).done(function(data){
var err = eval('(' + data + ')' ).responseStatus;
if (err == 200){
console.log("success with: " + data);
} else if (err == 400){
console.log("fail with: " + data);
console.log("removing from valid array");
v_feed.splice(v_feed.length - _, 1);
}
//console.log(err);
}).fail(function(){
console.log("Fail");
}).complete(function(){
console.log(v_feed);
});
});
答案 0 :(得分:2)
试试:
var arrayOfPromises = [];
//inside each/for loop, push request in array
arrayOfPromises.push($.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]}
}));
然后在循环之外:
$.when.apply($, arrayOfPromises).done(function(data){
//all requests are done
});
我不记得确切地将哪些数据传递给done(),检查它。
答案 1 :(得分:2)
使用$ .each循环,在发送ajax请求之前为html中的每个feed创建包装器,存储对包装器的引用。完成后,使用Feed填充包装器。这样您就可以一次性检索它们,同时仍以正确的顺序将它们添加到页面中,而无需等待它们全部完成。
$.each(feedArr, function(_,url){
var wrapper = $("<div>").appendTo(someel);
$.ajax("feed.php",{
type: "POST",
data: { url: url }
}).done(function(data){
// process data...
wrapper.append(generateFeedHTML(data));
}).fail(function(){
wrapper.remove();
});
});
答案 2 :(得分:1)
仅在成功时启动下一个电话:
var worked = {status:true},
conn = function(successLogic){
if(feed_a[i]) // I assume this is the loop end condition...
$.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]},
success: function(data){
if(successLogic(data));
worked.status = worked.status && conn(successLogic); // Recursion instead of iteration!
},
error: function(err){
worked.status = false;
// your error code
}
});
else
return worked;
};
var completedRecusionPromise = conn(function(data){
var obj;
try{
obj = JSON.parse(data);
}catch(e){ console.log(e); }
return !!obj; // Assuming you just want valid JSON??
});