2017-07-21 87 views
0

我有獲取調用此函數一次:從返回的for循環它有一個異步調用

exports.validate = function(roomData, callback) { 
    console.log('This only prints only once!'); 

    getAllRooms(function(rooms) { 
    if (rooms.length === 0) { 
     callback(true); 
     return; 
    } 

    for (let i = 0; i < rooms.length; i++) { 
     let key = "roomAdmin:" + rooms[i].roomName; 

     redis.hgetall(key, function() { 
     let newUrl = roomData.url.toLowerCase(); 
     let existingUrl = rooms[i].url.toLowerCase(); 
     let newRoomName = roomData.roomName.toLowerCase(); 
     let existingRoomName = rooms[i].roomName.toLowerCase(); 

     if (newUrl === existingUrl || newRoomName === existingRoomName) { 
      console.log('This prints'); 
      callback(false); 
      return; 
     } 
     if (i === rooms.length - 1) { 
      console.log('But this prints also?'); 
      callback(true); 
      return; 
     } 
     }) 
    } 
    }); 
}; 

我通過一組Redis的對象試圖循環和比較一些領域一些給新數據。如果有一場比賽,我想用虛假的回報進行回叫。如果沒有匹配,我想返回true。

我可以看到我的邏輯在下面是錯誤的,因爲hgetall是異步的,因此兩個返回都會被調用,所以如何在我找到匹配時立即停止執行並返回?

感謝

+0

你的邏輯並不完全錯誤,你有一個回調的參數,所以當結果那裏的代碼將正常繼續。但是,根本不需要返回,這不是觸發執行後面必須執行的代碼的事情。所有這些都必須在回調中完成,而不是在'validate'調用之後順序放置。一個簡單的解決方案是將'redis.hgetall'調用包裝在一個函數中,該函數將附加參數'i'和'callback'作爲var存儲。像這樣,'i'的值將是正確的 – Kaddath

回答

1

停止執行是以hgetall功能的責任,所以你可以用最簡單直接的解決方案 - 傳遞給它的陣列功能,這就要求當地讓分配的功能。找到匹配後(或發生錯誤),只需將本地函數替換爲空。現代ES解釋器優化器將足夠快地執行代碼,但不會執行額外的回調。

喜歡的東西如下:

let cbc = function() { 
    let newUrl = roomData.url.toLowerCase(); 
    let existingUrl = rooms[i].url.toLowerCase(); 
    let newRoomName = roomData.roomName.toLowerCase(); 
    let existingRoomName = rooms[i].roomName.toLowerCase(); 
    // ...... 
    if(found) { 
     cbc =() => {}; 
     callback(result); 
     return 
    } 
}  
// ...... 
redis.hgetall(key, (...args) => cbc(...args)); 
+0

在我的大腦中,有一些東西讓鐘聲響起。當沒有發現任何錯誤並且沒有錯誤發生時,如何調用回調函數?也許我錯了,但是這個代碼不依賴類似於同步的執行嗎?如果第一個實例比第二個實例需要更多時間來回答(並拋出錯誤),那麼第二個實例中是否仍然存在「cbc」函數? – Kaddath

+0

@Kaddath你說得對,它只是建議用例的代碼概念。當然,原來的'cbc'函數應該監視第n個調用次數,並且在最後一次迭代中執行假分支回調。關於異步執行,很可能,這不是問題,因爲每個閉包都有它自己的實例。再次 - 它主要回答問題'如何從異步回調返回',因此實現停止調用不可控制函數的回調。 –