我试图理解Jquery中的Promise。在下面的示例中,我尝试从数组加载一组 url,加载后,我想将文本附加到 html
array1 = ["helloworld.html", "helloworld.html", "helloworld.html"]
loadData(array1).then(function() {
$('pre').append("done");
});
function loadData(gim) {
for (i = 0; i < gim.length; i++) {
console.log(i);
$.get(gim[i], function(data) {
console.log("a = " + i);
$('pre').append(data+" -- "+i+"<br>");
});
}
}
但未附加文本"完成"。http://plnkr.co/edit/EEaQqfnUyVHGZBgDCRPs?p=preview 源代码
我在这里看到三个独立的问题。
- 当 ajax 调用完成时,循环索引是错误的,因为
for
循环在异步 ajax 调用完成之前已经运行了它的过程。 - 您需要找到一种方法来等到最后一个异步操作完成,然后再附加"done"。 你可以正确地使用承诺。
- 您的 ajax 结果不一定会按顺序追加,因为不确定 ajax 调用的完成顺序。 根据服务器体系结构和请求中涉及的内容,它们"可能"按请求顺序完成,但由于您并行运行它们,因此肯定不能保证。
第一个问题是因为操作是异步的,因此在异步操作完成时,循环索引处于最终值。请参阅此答案以获取该部分问题的解决方案。在此处查看使用您的代码实现的解决方案:http://plnkr.co/edit/cUFGZL0Bm6unRca3X7N5?p=preview
如果你想知道所有ajax操作何时完成,以便你可以附加"done",那么你将需要正确使用承诺。 您可以这样做:
<script>
array1 = ["helloworld.html", "helloworld.html", "helloworld.html"]
loadData(array1).then(function() {
$('pre').append("done");
}, function() {
// handle error here
});
function loadData(gim) {
var promises = [];
for (var i = 0; i < gim.length; i++) {
(function(index) {
console.log(index);
promises.push($.get(gim[index]).then(function(data) {
console.log("a = " + index);
$('pre').append(data+" -- "+index+"<br>");
}));
})(i);
}
return Promise.all(promises);
}
</script>
工作示例:http://plnkr.co/edit/KrC7Lxu9OHs9suvNOC8t?p=preview
在这里,您收集一个承诺数组,这些承诺由$.get()
返回到数组中,并使用Promise.all()
告诉您所有这些承诺何时完成。
仅供参考,此代码不保证结果将按顺序附加,因为异步操作可以按任何顺序完成。
如果要并行运行操作,但要确保按请求的顺序添加它们,则可以像这样更改代码以收集所有结果,然后按保证顺序将结果添加到 DOM:
<script>
array1 = ["helloworld.html", "helloworld.html", "helloworld.html"]
loadData(array1).then(function() {
$('pre').append("done");
}, function() {
// handle error here
});
function loadData(gim) {
var promises = [];
for (var i = 0; i < gim.length; i++) {
promises.push($.get(gim[i]));
}
return Promise.all(promises).then(function(results) {
results.forEach(function(item, index) {
$('pre').append(item + " -- "+index+"<br>");
});
});
}
</script>
工作示例:http://plnkr.co/edit/nUHwFMg22V8rc9v12SqR?p=preview
如果你只想使用 jQuery promise 函数(有点不标准),你可以这样做:
<script>
array1 = ["helloworld.html", "helloworld.html", "helloworld.html"]
loadData(array1).then(function() {
$('pre').append("done");
}, function() {
// handle error here
});
function loadData(gim) {
var promises = [];
for (var i = 0; i < gim.length; i++) {
promises.push($.get(gim[i]));
}
return $.when.apply($, promises).then(function() {
var results = Array.prototype.slice.call(arguments);
console.log(results);
results.forEach(function(item, index) {
$('pre').append(item[0] + " -- "+index+"<br>");
});
});
}
</script>
工作示例:http://plnkr.co/edit/IHMnEbYEFLjfguDkoubg?p=preview