2013-08-21 65 views
0

我在Node.js中有異步查詢。變量sq3是一個連接變量。 例如是這樣的:如何從節點js中的回調函數中斷開循環?

for (var i in res) { 
    if (i == 1) { 
    sq3.query("SELECT * from students;", 

     function (err, res) { 
     if (err) { 
      throw err; 
     } else { 
      if (res.length == 1) { 
      //do something 
      } else { 
      //break for 
      } 
     } 
     }); 

    sq3.end(); 
    } 
} 

如何從回調函數打破? 謝謝

+0

只寫'返回;' – exexzian

+0

我想打破循環的,不只是從回調函數 – Edgar

+0

那麼簡單break語句應該爲 – exexzian

回答

0

在你的代碼片段中,你不能從回調函數中斷開。在node.js中,回調函數在稍後未指定的時間在同一個線程上運行。這意味着,但回調函數執行的時間,for循環早已結束。

爲了獲得您想要的效果,您需要非常顯着地重構您的代碼。以下是你如何做到這一點的例子(未經測試!!)。想法是繼續使用項目列表調用doSomething(),每次縮減一個元素,直到達到所需結果(您的中斷條件)。

function doSomething(res) 
{ 
    while (res.length > 0) 
    { 
     i = res.shift(); // remove the first element from the array and return it 
     if (i == 1) 
     { 
      sq3.query("SELECT * from students;", 
       function(err, res) { 
        if (err) 
        { 
         throw err; 
        } 

        if (res.length==1) 
        { 
         //do something 

         // continue with the remaining elements of the list 
         // the list will shrink by one each time as we shift off the first element 
         doSomething(res); 
        } 
        else 
        { 
         // no need to break, just don't schedule any more queries and nothing else will be run 
        } 
       }); 

      sq3.end(); 
      break; // break from the loop BEFORE the query executes. We have scheduled a callback to run when the query completes. 
     } 
    } 
} 
+0

迭代循環只是查找相當於1的項目,然後在數據庫中查詢。數據庫查詢完成後,它終止或繼續迭代剩餘的元素,直到找到另一個等於1.因此,我確定它是等價的。 –

+1

其實我剛剛意識到傳遞給原函數的'res'變量被重用作查詢回調函數的一個參數。我沒有注意到同一個變量名正在被重用,所以我的代碼不會像上面那樣工作。我不確定OP想要實現什麼,但是我的基本解決方案是遞歸地在列表中移動「仍然存在! –

+0

是的,現在你看到它了。我只是雙重檢查自己。你的邏輯思想是正確的,實際上相當於我的。您的迭代循環添加(如果正確地與遞歸結合以不重新訪問值)可能實際上有助於性能(微優化)。你確實提到它沒有經過測試,所以我會給你那一個:)如果你以一種愚蠢的方式編輯你的答案,我會刪除我的downvote給出的評論 – ChrisCM

5

只要做到這一點,使用遞歸而不是循環。這不僅可以讓你實現你想要的邏輯。它也不會立即啓動一堆異步請求。它們依次執行,但是是異步執行的,所以它仍然是高性能的。

function lookatEntireResponse(res) { 

    function lookAtItemInResponse(item) { 
     if(item == 1) { 
      sq3.query("SELECT * from students;", 

       function(err, res) { 
        if (err) 
        { 
         throw err; 
        } 

        else 
        { 
         if(res.length==1) 
         { 
          doSomething(item); 
          lookAtItemInResponse(res.shift()); 
         } 
         else 
         { 
          //just don't call the next lookAtItemInResponse function, effectively same thing as "break;" 
         } 

        } 
       }); 

      sq3.end(); 
     } else { 
      lookAtItemInResponse(res.shift()); 
     } 
    } 

    lookAtItemInResponse(res.shift()); 

} 

你可以考慮節流的同時請求具有類似的邏輯(比如允許每個lookAtItem電話10個這樣的請求。這樣就可以實現這兩種方法的混合,然後只需優化性能的同時請求數。在異步庫使得這樣的東西更容易