我在循环和对象数组之后发送另一个AJAX调用时遇到问题。代码如下
var def = true;
$.each(urls, function(index, val) {
var postResult = $.Deferred();
link = 'http://myurl.com' + val.aslug + '/' + val.slug;
$.when(def).then(function(){
$.post('https://graph.facebook.com ', {id : link, scrape : 'true' }, function(data, textStatus, xhr) {
}).always(function(){
postResult.resolve(5);
});
});
def = postResult;
});
问题是第一次和第二次打电话他们没问题。但第三个调用和以下调用与第二个调用相同:/我认为每个调用都没有更改为下一个对象
答案 0 :(得分:2)
在这种情况下最简单的方法是: 在" when-then"内部移动变量链接分配构造
var def = true;
$.each(urls, function(index, val) {
var postResult = $.Deferred();
$.when(def).then(function(){
var link = 'http://myurl.com' + val.aslug + '/' + val.slug;
$.post('https://graph.facebook.com ', {id : link, scrape : 'true' }, function(data, textStatus, xhr) {
}).always(function(){
postResult.resolve(5);
});
});
def = postResult;
});
由于JS异步能力,你遇到了这个问题。 $ .each() - 循环根本不会等待你的"延迟的代码片段"将运行。它通过你的数组循环并创建一个将要执行的任务队列。
另外,您可以考虑将$.AJAX
与async:False
选项一起使用,而不是
答案 1 :(得分:1)
你的直觉是正确的 - 最大的问题是你不想在循环中创建一个函数。当$.when
第二次解析时,该闭包内的link
变量将不再引用正确的值。这就是为什么你要收到一堆相同网址的电话。
另外,要创建一系列promise,你会想要使用这样的东西:https://github.com/kriskowal/q#sequences(不确定jQuery promises是否具有类似功能)
示例代码:
// not sure if this is necessary
// haven't used jQuery promises much
var result = $.when(true);
mapUrlsToPosts(urls).forEach(function(f) {
result = result.then(f);
});
function mapUrlsToPosts(urls) {
return urls.map(function(url) {
// create a function that when executed will make a request to the desired url
return post.bind(null, url);
});
}
function post(val) {
var link = 'http://myurl.com' + val.aslug + '/' + val.slug,
postResult = $.Deferred(),
params = {
link: link,
scrape: 'true'
};
$.post('https://graph.facebook.com ', params, function(data, textStatus, xhr) {
}).always(function(){
postResult.resolve(5);
});
return postResult;
}
编辑:顺便说一下,如果你不需要在下一个请求完成之前等待上一个请求完成,那么所有这些都可以变得更加简单。这里的大部分复杂性来自排队请求。