Javascript:等待循环中的函数在下一次迭代之前完成执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24131480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript: wait for function in loop to finish executing before next iteration
提问by user2973438
$(function() {
$("#submit").click(function() {
for (var i=1; i<=14; i++)
{
setID(i);
checkField(i);
}
if ($('#pass_fail').val() != "fail")
{
//do something
}
This is what happens when I click on the submit button of a registration form.
当我点击注册表单的提交按钮时会发生这种情况。
Order of execution I want:
我想要的执行顺序:
setID(1);
checkField(1); //wait for this to finish
setID(2);
checkField(2);
setId(3);
checkField(3);
....
if statement
设置 ID(1);
检查字段(1);//等待此操作完成
setID(2);
checkField(2);
设置 ID(3);
检查字段(3);
....
if 语句
Order of execution I get:
我得到的执行顺序:
for loop going from i=1 to i=14
if statement
checkField(i)s in random order
for 循环从 i=1 到 i=14
if 语句
checkField(i)s 以随机顺序
Problem: $('#pass_fail').val() has a default value of 'pass'. However through the loop checkField(i) might change its value to 'fail'. But since in reality the if statement is executed before checkField(i)s, the value of $('#pass_fail') always ends up being 'pass' and the 'do something' always executes.
问题:$('#pass_fail').val() 的默认值为“pass”。但是,通过循环 checkField(i) 可能会将其值更改为“失败”。但由于实际上 if 语句是在 checkField(i)s 之前执行的,$('#pass_fail') 的值总是以 'pass' 结束并且'do something' 总是执行。
How do I wait for checkField(i) to finish executing before moving on to the next iteration of the looP? Thank you in advance!
在进入循环的下一次迭代之前,如何等待 checkField(i) 完成执行?先感谢您!
采纳答案by jfriend00
I'm assuming from your description of the issue that checkField()
is making some sort of asynchronous Ajax call. If you truly want to serialize the calls to checkField()
so the 2nd call is not made until the first has completed, then you need to change the structure and flow of your code in order to do that. The two common ways of doing so are either using a callback that indicates completion of a call to checkField()
that triggers the next call to checkField()
or the use of promises to accomplish something similar.
根据您对checkField()
进行某种异步 Ajax 调用的问题的描述,我假设。如果您真的想将调用序列化,checkField()
以便在第一个调用完成之前不会进行第二个调用,那么您需要更改代码的结构和流程才能做到这一点。这样做的两种常见方法是使用回调指示对checkField()
触发下一次调用的调用的完成,checkField()
或者使用承诺来完成类似的事情。
Here's an example of the callback mechanism:
下面是回调机制的一个例子:
$("#submit").click(function() {
var i = 0;
function next() {
i++;
if (i <= 14) {
setID(i);
checkField(i, next);
} else {
// all checkField operations are done now
if ($('#pass_fail').val() != "fail") {
//do something
}
}
}
next();
});
Then, checkField()
would have to be modified to call the callback passed to it when it completes its asynchronous operation.
然后,checkField()
当它完成其异步操作时,必须修改以调用传递给它的回调。
If you're using jQuery to make the ajax operations inside of checkField, it would be fairly easy to use jQuery promises to solve this also.
如果您使用 jQuery 在 checkField 内进行 ajax 操作,那么使用 jQuery 承诺也可以很容易地解决这个问题。
回答by ArifMustafa
Sorry, but in earlier response I didn't see any loop to wait for any other function or any inner loop execution to let it finish before next iteration.
抱歉,但在之前的回复中,我没有看到任何循环等待任何其他函数或任何内部循环执行以使其在下一次迭代之前完成。
With JQuery 3.3.1
和 JQuery 3.3.1
Scenario:
for loop
with var i
will wait for inner other loop to complete before next iteration value of i
场景:
for loop
withvar i
将在下一次迭代值之前等待内部其他循环完成i
$(document).ready(function(){
$("p").click(function() {
var varIDeferred = $.Deferred();
var varJDeferred = $.Deferred();
/*
var loopJInside = function(j) {
console.log("j is : " + j);
$("span").html($("span").html() + "<br>j is : " + j);
varJDeferred.resolve();
j++;
console.log("j value after incr is : " + j);
return j;
}
// call inside loopJ
setTimeOut(j = loopJInside(j), 500);
*/
var loopJ = function(valueI) {
for (var j = valueI; j < (3+valueI); ) {
varJDeferred = $.Deferred();
$("span").html($("span").html() + "<br>j is : " + j);
j++;
varJDeferred.resolve();
}
varIDeferred.resolve();
return (valueI+1);
};
for(var i = 0; i < 3; ) {
varIDeferred = $.Deferred();
$("span").html($("span").html() + "<br>value of i is : " + i);
if (i == 3)
break;
i = loopJ(i);
};
});
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<p style="cursor:default;border:2px solid black;width:60px;padding:5px;">Click me</p>
<span><span>
</body>
</html>
Hope this would help many one.
希望这会帮助很多人。