javascript Javascript在回调函数中破坏for循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11842686/
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 breaking a for loop inside a callback function
提问by eirikrl
I have code like the following:
我有如下代码:
function test(obj) {
if(//some conditon) {
obj.onload();
}else{
obj.onerror();
}
}
for(var i=0;i<4;i++){
test({
onload:function(e){
//some code to run
},
onerror:function(e){
break;
}
});
}
The gist is the test() function is a function to make an XHR request (it is actually an API of the Appcelerator Titanium platform so I have no control over it) and I'm looping something to call the test function. I need to break the loop on the onerror function, but I get an error saying the break is not inside a loop or switch statement. How can I rewrite this?
要点是 test() 函数是一个发出 XHR 请求的函数(它实际上是 Appcelerator Titanium 平台的 API,所以我无法控制它)并且我正在循环调用测试函数。我需要中断 onerror 函数上的循环,但我收到一条错误消息,指出中断不在循环或 switch 语句中。我怎样才能重写这个?
回答by penartur
If your code sample does represent some actual code (i.e. all the processing is done in the same event loop tick), you may do the following:
如果您的代码示例确实代表了一些实际代码(即所有处理都在同一个事件循环滴答中完成),您可以执行以下操作:
function test(obj) {
if (some_condition) {
return obj.onload();
} else {
return obj.onerror();
}
}
var result;
for(var i=0; i<4; i++){
result = test({
onload:function(e){
//some code to run
return true;
},
onerror:function(e){
return false;
}
});
if (!result) {
break;
}
}
Otherwise, if there is something asynchronous done, you have to call test
sequentially, and not in parallel. For example,
否则,如果有一些异步完成,你必须test
顺序调用,而不是并行调用。例如,
function test(obj) {
doSomeAjaxRequest(arguments, function (err, result) {
if (some_condition) {
obj.onload();
} else {
obj.onerror();
}
});
}
var f = function (i) {
if (i >= 4) return;
test({
onload:function(e){
//some code to run
f(i+1);
},
onerror:function(e){
break;
}
});
}
f(0);
回答by Lode Michels
Bit hacky maybe but one could do something like this with a handler function.
也许有点hacky,但可以用处理程序函数做这样的事情。
var handler = function(array, callback){
for(var i=0, l=array.length, e=array[i]; i<l; ++i){
if(true === handler.exit){
handler.exit = false; //restore
return;
}
callback.call(null, e);
}
};
handler.exit = false;
handler([1,2,3], function(e){
console.log(e);
if(2 === e){
arguments.callee.caller.exit = true; // :-)
}
});
Didn't test this but maybe you could bind function to scope in call even?
没有对此进行测试,但也许您甚至可以将函数绑定到调用范围?
var handler = function(a, f){
this.exit = false;
for(var i=0, l=a.length, e=a[i]; i<l; ++i){
if(true === this.exit){
this.exit = false; //restore
return;
}
callback.call(this, e);
}
};
handler([1,2,3], function(e){
console.log(e);
if(2 === e){
this.exit = true;
}
});
回答by just.another.programmer
Not possible. A for loop is a synchronousprocedure while an Ajax request is not. That means when the onerror callback happens, the for loop is already doneexecuting.
不可能。for 循环是一个同步过程,而 Ajax 请求则不是。这意味着,当使用onerror回调发生,for循环已经完成执行。
As an alternative you could introduce a check into your onsuccess handler which confirms no errors have happened yet.
作为替代方案,您可以在您的 onsuccess 处理程序中引入检查,以确认尚未发生错误。
var errorOccured = false;
for(var i=0;i<4;i++){
test({
onload:function(e){
if(errorOccured) return;
//some code to run
},
onerror:function(e){
errorOccured = true;
}
});
}
回答by user3300510
I take the answer of penartur, but I modified without the "break":
我接受了 penartur 的回答,但我修改了没有“break”:
function test(obj) {
doSomeAjaxRequest(arguments, function (err, result) {
if (some_condition) {
obj.onload();
} else {
obj.onerror();
}
});
}
var f = function (i) {
if (i >= 4) return;
test({
onload:function(e){
//some code to run
f(i+1);
},
onerror:function(e){
console.log('stop');
}
});
}
f(0);
回答by Vladimir Kadalashvili
You cannot break the loop inside test() function. I think the best solution in this case would be to throw an exception inside test() function, then catch it in the loop and break.
你不能打破 test() 函数内部的循环。我认为在这种情况下最好的解决方案是在 test() 函数中抛出一个异常,然后在循环中捕获它并中断。
回答by Wiebe Tijsma
Maybe you can make the 'onload' callback recursive?
也许您可以使“onload”回调递归?
Meaning, you just call the 'test' method inside the 'onload' handlerr, this would also mean you fire all requests in order instead of all at the same time.
这意味着,您只需在“onload”处理程序中调用“test”方法,这也意味着您按顺序触发所有请求,而不是同时触发所有请求。