在这个for循环中,我希望强制它首先运行AJAX代码块。结果(即 data.LocationId ),我想将其保存在服务器上,然后在 i 减少的情况下运行循环。
如果你看到我的console.log,我希望它可能是:
asyncProcess
data.LocationId 7615
asyncProcess
data.LocationId 7614
asyncProcess
data.LocationId 7613
但实际上是:
asyncProcess
asyncProcess
asyncProcess
data.LocationId 7615
data.LocationId 7614
data.LocationId 7613
如何实现这一目标?
这是我的代码:
for (i = projectAreaSet.length-1; i >= 0; i--)
{
function asyncProcess(geometry)
{
console.log("asyncProcess");
var deferred = new Deferred(); //Dojo, not jQuery
var locationProfile = { ProjectId: projectId }
$.ajax({
type: "POST",
data: JSON.stringify(locationProfile),
url: "api/LocationProfile/Create",
contentType: "application/json",
})
.success(function (data)
{
LocationIdSet.push(data.LocationId);
console.log("data.LocationId ", data.LocationId);
var currentProjectGraphic = new esri.Graphic(geometry, newSymbol, attributes =
{ "ID": data.LocationId, "Type": 1}, null);
var currentLayer = that.map.getLayer("Project");
currentLayer.applyEdits([currentProjectGraphic], null, null);
deferred.resolve();
});
return deferred.promise;
}
var saveProject = asyncProcess(projectAreaSet[i]);
}
答案 0 :(得分:1)
由于你的ajax调用似乎彼此独立(一个不依赖于另一个),你可以并行运行它们并使用promises来保持结果的顺序,这样你就可以处理结果有序。这通常是一个更快的端到端执行时间,但仍然可以让您按顺序处理结果。你可以使用像这样的jQuery承诺来做到这一点:
var promises = [];
for (var i = projectAreaSet.length - 1; i >= 0; i--) {
(function(geometry) {
promises.push($.ajax({
type: "POST",
data: JSON.stringify({ProjectId: projectId}),
url: "api/LocationProfile/Create",
contentType: "application/json"
}).then(function(data) {
// make resolved value be data and geometry together so we can
// process them in order together later
return {geometry: geometry, data: data};
}));
})(projectAreaSet[i]);
}
$.when.apply($, promises).then(function() {
var results = Array.prototype.slice.call(arguments);
// process results array here in the order they were requested
results.forEach(function(obj) {
var data = obj.data;
var geometry = obj.geometry;
LocationIdSet.push(data.LocationId);
console.log("data.LocationId ", data.LocationId);
var currentProjectGraphic = new esri.Graphic(geometry, newSymbol, attributes = {
"ID": data.LocationId,
"Type": 1
}, null);
var currentLayer = that.map.getLayer("Project");
currentLayer.applyEdits([currentProjectGraphic], null, null);
});
// all results processing done here - can run any final code here
});
答案 1 :(得分:0)
虽然我支持jfriend00关于并行运行请求的建议,但你特别问:
如何实现这一目标?
如果你真的希望它们按顺序/顺序运行,那么一种技术就是从 success()回调中运行下一次迭代。
在下面的代码中, for 语句已被删除, i 已成为函数 asyncProcess()的参数。然后在成功回调中,如果 i 的值大于0,则在从 i 中减去一个值后再次调用该函数(就像 i 一样/ em>循环确实)。
var i = projectAreaSet.length - 1;
asyncProcess(projectAreaSet[i], i);
function asyncProcess(geometry, i) {
$.ajax({
type: "POST",
//...other options
})
.success(function(data) {
LocationIdSet.push(data.LocationId);
//instantiate new esri.Graphic, call currentLayer.applyEdits()
//then run the next iteration, if appropriate
if (i > 0) {
asyncProcess(projectAreaSet[i-1], i-1);
}
deferred.resolve();
});
请参阅this plunker中演示的内容。
在阅读了答案的讨论之后,看起来你的目标是采用平行的方法。为此,由于正在使用jQuery,请查看使用.when()函数 - 传递一组promise(例如,$.ajax()返回)。
看看this updated plunker。您会注意到函数 asyncProcess 已更新,以返回对$.ajax()
的调用,...
是一个jqXHR对象,“实现了Promise接口“ 1
使用该更改,可以将promise添加到数组中。然后使用spread operator(即$.when(...promises).done(function() { ... });
)将承诺传递给$.when。
$.when.apply(null, promises).done(function() { ... });
在ES-6中添加了传播运算符,因此IE之类的旧版浏览器不支持它。如果此类浏览器需要支持,apply可用于使用这些承诺调用$.when。
$.when()
在对var promises = [];
for (i = projectAreaSet.length - 1; i >= 0; i--) {
promises.push(asyncProcess(projectAreaSet[i], i));
}
$.when(...promises).done(function() {
Array.prototype.forEach.call(arguments, function(response) {
var data = response[0];
console.log("data.LocationId ", data.LocationId);
LocationIdSet.push(data.LocationId);
geometry = projectAreaSet[data.i];
/* continue with normal code:
var currentProjectGraphic = new esri.Graphic(geometry, newSymbol, attributes =
{ "ID": data.LocationId, "Type": 1}, null);
var currentLayer = that.map.getLayer("Project");
currentLayer.applyEdits([currentProjectGraphic], null, null);*/
});
});
的调用的 .done()回调中,每个参数都是一个数组,其中第一个元素是数据。总而言之,我们有如下代码:
GetSystemMenu
† 嗯,实际上你在the original post中问了“ 如何实现这个目标 ”但有人编辑了你的交... 子> 1 <子> https://api.jquery.com/jquery.post/#jqxhr-object 子>