回答
你不这样做同步AJAX在浏览器(以及从技术上讲,你可以在某些情况下,但它是一个非常糟糕的主意,这样做是因为它在Ajax调用期间锁定了浏览器)。
相反,您重新设计您的循环,以便只在前一个循环完成时执行下一个Ajax调用,这意味着您必须手动循环,否则不能使用for
循环。由于你的代码是伪代码(你不显示真正的ajax操作),我将使用jQuery ajax示例,但只要它返回一个承诺或使用回调来代替您拥有的任何ajax函数信号完成后。
一般的想法是,你为你的ajax调用创建一个函数,并使用它的完成回调增加你的索引,然后运行你的循环的下一次迭代。
function runLoop(data) {
var i = 0;
function next() {
if (i < data.length) {
return $.ajax(data[i]).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(someArray).then(function() {
// all done here
});
如果你没有数据的数组,但只想要一个循环索引:
function runLoop(limitVar) {
var i = 0;
function next() {
if (i < limitVar) {
return $.ajax(something_with_i_in_it).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
如果limitVar不大,有参与决定是否继续没有其他逻辑环路,也可以使用一点点简单的模式,如果你有一个返回一个承诺一个Ajax功能:如果你没有使用返回一个承诺AJAX功能
function runLoop(limitVar) {
var p = Promise.resolve();
for (var i = 0; i < limitVar; i++) {
p = p.then(function(prevResult) {
return someAjax(i);
});
}
return p;
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
,那么它只是一个几行代码将你的函数封装起来,然后你可以更容易地使用这些设计模式。
为什么downvote?这个答案有什么问题?如果您提供反馈,说明为什么它被低估,那么人们只能改善他们的答案来解决反对意见。 – jfriend00
使用一些单独的函数处理数组。每次你从数组中取下另一个元素,然后处理它,当它完成时再次调用该函数。如果列表中没有更多项目,则整个过程完成。
var listOfRequests = ...; new Promise(function(resolve, reject) { requestNext(); function requestNext() { if (!listOfRequests.length) { return resolve(); } var next = listOfRequests.shift(); doAjaxStuff(next, reject, requestNext); } }) doAjaxStuff(request, errCallback, doneCallback) { ... }
这是一个非常简单的模式:
var queue = Promise.resolve();
var nop =() => null;
for(let i=0; i<limitVar; ++i){
queue = queue.then(() => doAjaxStuff(i));
//or if you want to ignore Errors
//queue = queue.then(() => doAjaxStuff(i)).catch(nop);
}
queue.then(() => console.log("finished"));
或者,如果你使用一个数组作为输入:
var done = data.reduce(
(queue, value, index) => queue.then(() => doSomethingWith(value, index)),
Promise.resolve()
);
done.then(() => console.log("finished"));
- 1. 承诺图遍历
- 2. 遍历JavaScript的承诺树
- 3. 遍历集合同步
- 4. 同步AJAX(违反诺言)
- 5. ajax的承诺
- 6. 承诺与异步和同步问题 - 角
- 7. 如何拒绝同步和异步代码功能的承诺?
- 8. ES6异步承诺
- 9. 同步循环内的承诺?
- 10. Javascript承诺:然后()的不同步
- 11. 在同步功能中使用承诺
- 12. 使用lodash链承诺同步数据
- 13. DOM遍历的AJAX调用遍历
- 14. 使用.join在异步承诺中调用异步承诺
- 15. 在遍历对象属性时解析或拒绝承诺
- 16. Javascript承诺和异步代码
- 17. 嵌套异步jquery承诺
- 18. sqlite3 - 承诺异步调用
- 19. 与承诺异步循环?
- 20. 异步使用javascript承诺
- 21. Q - 链接同步的承诺,处理成功和失败
- 22. 测试承诺和同步功能,抛出错误
- 23. Bash脚本递归遍历目录,比较和同步文件
- 24. Cypher中的多步遍历?
- 25. Powerquery遍历步骤列表
- 26. 链接承诺,以应付来自this.storage.get()调用异步承诺
- 27. 承诺内承诺
- 28. 承诺拒绝失败,承诺承诺
- 29. 承诺中的承诺承诺
- 30. 同步Ajax Toolkit日历扩展器
@KevinB Promise.all()被发射一次的所有请求。如果数组足够大,肯定会耗尽导致请求失败的资源。 – cepharum
您可以使用[] .reduce创建一个接一个地调用它们的链。例如:https://stackoverflow.com/questions/21372320/how-to-chain-execution-of-array-of-functions-when-every-function-returns-deferre –
转向承诺意味着转向异步。 – Bergi