用 jQuery 接一个 AJAX 呼叫
Send one AJAX call after the other with jQuery
我在循环和对象数组时发送一个 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;
});
问题是第一次和第二次都正常。但是第三次调用和以下调用与第二次调用相同:/我认为每个对象都没有更改为下一个对象
在这种情况下,最简单的方法是:
在 "when-then" 构造中移动变量 link 赋值。
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() - 当您的 "deferred piece of code" 变为 运行 时,循环不会等待。它循环遍历您的数组并创建将要执行的任务队列。
您也可以考虑使用 $.AJAX
和选项 async:False
,而不是
您的直觉是正确的 - 最大的问题是您不想在循环中创建函数。当 $.when
第二次解析时,闭包内的 link
变量将不再引用正确的值。这就是为什么你会收到一堆相同的 url.
的电话
此外,要创建一系列承诺,您将要使用如下内容:https://github.com/kriskowal/q#sequences(不确定 jQuery 承诺是否具有类似功能)
示例代码:
// 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;
}
编辑:顺便说一句,如果您不需要等待上一个请求完成再进行下一个请求,那么所有这一切都可以变得更加简单。这里的大部分复杂性来自排队请求。
我在循环和对象数组时发送一个 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;
});
问题是第一次和第二次都正常。但是第三次调用和以下调用与第二次调用相同:/我认为每个对象都没有更改为下一个对象
在这种情况下,最简单的方法是: 在 "when-then" 构造中移动变量 link 赋值。
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() - 当您的 "deferred piece of code" 变为 运行 时,循环不会等待。它循环遍历您的数组并创建将要执行的任务队列。
您也可以考虑使用 $.AJAX
和选项 async:False
,而不是
您的直觉是正确的 - 最大的问题是您不想在循环中创建函数。当 $.when
第二次解析时,闭包内的 link
变量将不再引用正确的值。这就是为什么你会收到一堆相同的 url.
此外,要创建一系列承诺,您将要使用如下内容:https://github.com/kriskowal/q#sequences(不确定 jQuery 承诺是否具有类似功能)
示例代码:
// 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;
}
编辑:顺便说一句,如果您不需要等待上一个请求完成再进行下一个请求,那么所有这一切都可以变得更加简单。这里的大部分复杂性来自排队请求。