2012-08-07 34 views
9

裏面我有這樣的代碼如下:的Javascript打破for循環的回調函數

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; 
     } 


    }); 
} 

要點是測試()的功能是使一個XHR請求的功能(它實際上是對一個API Appcelerator Titanium平臺,所以我無法控制它),我正在循環一些東西來調用測試函數。我需要打破onerror函數的循環,但是我得到一個錯誤,告訴break不在循環或switch語句中。我該如何重寫?

+1

感謝我只投了過去回答上來,但現在我知道打對勾 – eirikrl 2012-08-07 09:33:34

回答

11

如果您的代碼示例確實代表了一些實際的代碼(即所有的處理是在同一事件循環打勾做),你可以做到以下幾點:

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); 
0

你不能打破test()函數內部的循環。我認爲在這種情況下最好的解決方案是在test()函數內拋出一個異常,然後在循環中捕獲它並中斷。

2

不可能。 for循環是一個同步過程,而Ajax請求不是。這意味着當發生onerror回調時,for循環已經執行完成執行。

作爲一種替代方案,您可以在您的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; 
    } 


}); 
} 
0

也許你可以使'onload'回調遞歸嗎?

意思是說,您只需在'onload'處理程序中調用'test'方法,這也意味着您可以按順序激活所有請求,而不是同時激活所有請求。

3

有點哈克也許,但一個人可以做這樣的處理函數。

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; 
    } 
}); 
0

我拿penartur的答案,但我修改沒有「休息」:

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);