Javascript破坏了回调函数内部的for循环
Javascript breaking a for loop inside a callback function
我有如下代码:
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;
}
});
}
要点是test()函数是一个发出XHR请求的函数(它实际上是Appcelerator Titanium平台的API,所以我无法控制它),我正在循环一些东西来调用测试函数。我需要中断oneror函数的循环,但我收到一个错误,说中断不在循环或switch语句中。我该如何重写?
如果您的代码样本确实代表了一些实际的代码(即所有处理都在同一事件循环中完成),您可以执行以下操作:
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;
}
}
否则,如果有异步操作,则必须按顺序调用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);
不可能。for循环是同步过程,而Ajax请求不是。这意味着当oneror回调发生时,for循环已经完成执行。
作为一种选择,您可以在您的成功处理程序中引入一个检查,以确认尚未发生任何错误。
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;
}
});
}
可能有点麻烦,但可以用处理程序函数做这样的事情。
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; // :-)
}
});
并没有对此进行测试,但也许您甚至可以在调用中将函数绑定到作用域?
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;
}
});
您不能破坏test()函数内部的循环。我认为在这种情况下,最好的解决方案是在test()函数中抛出一个异常,然后在循环中捕获它并中断。
也许您可以使"onload"回调递归?
也就是说,你只需要在"onload"handlerr中调用"test"方法,这也意味着你要按顺序而不是同时触发所有请求。
我接受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);
相关文章:
- 为什么JavaScript在for循环为3时向所有4发出警报
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- 我的javascript for循环不起作用
- For循环冻结Javascript
- 如何在for循环中添加事件侦听器
- 双“for”循环(循环)
- javascript for循环不起作用
- for循环中的javascript if语句找不到==
- Javascript在for循环中等待处理请求
- For循环在Jquery中只运行一次
- 如何在for循环中使用计数器
- for循环中的JavaScript闭包
- 为什么我们在ES2015中需要一个新的for循环结构,而我们已经有了for、forEach
- For循环在调用时未运行
- 如何使用for循环添加所有按钮'单击事件
- 如何更改在for循环中生成的圆的位置
- 为什么这个For循环会使浏览器实验室崩溃
- 为什么我使用javascript获得了一个无限的for循环
- 在for循环中使用多维数组设置google.maps.Marker图标
- 如何在angularJS中运行for循环而不使用html标记