2016-06-08 38 views
0

我之前發佈了一個問題,並意識到我的問題實際上是異步函數。我設法解決了大部分問題,但我還有一個小問題。使用異步I用來瀑布創造了一些查詢訂單...回調,直到循環查詢完成

exports.getMenu = function(id_restaurant, callback){ 
    async.waterfall([ 
     async.apply(firstQuery, id_restaurant), 
     secondQuery, 
     thirdQuery, 
     fourthQuery, 
     formMenu 
    ], function(err, result){ 
     if(err){ 
      console.log(err); 
     } 

     callback(result); 
    }); 
}; 

一切正常,直到fourthQuery,在那裏我有循環得到一個菜單的所有菜餚。

function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){ 
    var size = array_nombresSecc.length; 
    var array_secciones = array_secciones; 
    var array_nombresSecc = array_nombresSecc; 

    var dishes = []; 

    pool.getConnection(function(err, connection) { 

     if(err) { 
      console.log(err); 
      callback(true); 
      return; 
     } 
     for (var i = 0; i < size; i++) { 
      connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]], 
       function(err, results2) { 
        if(err) { 
         console.log(err); 
         callback(true); 
         return; 
        } 

        console.log("Result query 4 " + JSON.stringify(results2)); 
        dishes[i] = results2; 
        console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i])); 
        // this prints the result but only if it has a value over 2 
      }); 
     }; 
    }); // pool 

    console.log("I'm sending " + dishes); // this logs an empty array 

    callback(null, dishes, array_nombresSecc); 
}; 

所以,我可以看到,從打印的「i」的每個循環的是,它始終爲2的值,因爲這是「大小」值的值發生。此外,即使它保存了索引'2'的結果,我相信回調仍在for循環完成之前完成,因爲我的第五個函數正在接收一個空數組。

如何讓我的代碼等待回調,直到我的for循環完成?

注意:對不起,我的部分代碼是西班牙文,試圖翻譯它的重要部分。

回答

1

有幾種方法可以解決這個問題,一種方法是查看承諾架構。 Promise.all將允許您提供一個回調來處理每個子承諾的值。然而,爲了使用你已經得到的東西,我會將值推入你的盤子數組,而不是專門將它們分配給i索引,然後在每個連接結束時檢查該數組的大小。當數組長度匹配大小時,觸發回調。 (如下圖所示)

如果您需要一種方法來每個結果綁定到特定i價值,我建議推動他們爲對象

dishes.push({'index': i, 'dish': results2}) 

之後,如果你需要的只是菜的陣列,您可以通過該索引值對數組進行排序並運行映射函數。

dishes.sort(function(a,b){ return a.index - b.index; }) 
dishes = dishes.map(function(a){ return a.dish }) 

這裏的調整代碼:

function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback) { 
 
    var size = array_nombresSecc.length; 
 
    var array_secciones = array_secciones; 
 
    var array_nombresSecc = array_nombresSecc; 
 

 
    var dishes = []; 
 

 
    pool.getConnection(function(err, connection) { 
 

 
    if (err) { 
 
     console.log(err); 
 
     callback(true); 
 
     return; 
 
    } 
 
    for (var i = 0; i < size; i++) { 
 
     connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]], 
 
     function(err, results2) { 
 
      if (err) { 
 
      console.log(err); 
 
      callback(true); 
 
      return; 
 
      } 
 

 
      console.log("Result query 4 " + JSON.stringify(results2)); 
 
     
 
     
 
      dishes.push(results2) 
 
      
 
      if(dishes.length == size){ 
 
      console.log("I'm sending " + dishes); 
 
      callback(null, dishes, array_nombresSecc) 
 
      } 
 
     
 
     
 
      console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i])); 
 
      // this prints the result but only if it has a value over 2 
 
     }); 
 
    }; 
 
    }); // pool 
 

 
    ; 
 
};

+0

是的,我需要將每個結果綁定到索引,但正如我所說....當我嘗試使用我時,它只說它有一個值,這使我失去了關係。推送解決方案使數組到達第五功能,但沒有關係(我的意思是他們共享索引)。[{「index」:2,「盤子」:[{「名稱」:「肋眼」,「價格」:180},{「名稱」:「牛仔」,「價格」:150},{「指數」名稱「:」Top-Sirloine「,」price「:195}],{」index「:2,」dishes「:[{」name「:」Coca-Cola「,」price「:30}名稱「:」雪碧「,」價格「:45} – Alan

+0

好吧,它的工作和你的答案是最幫助我的。標記爲正確。 我添加了一個計數器到我的方法,並在檢查如果dishes.length ==大小之前,我只是做counter ++和使用保存該計數器作爲索引。這使得伎倆,謝謝。 – Alan

0

既然你已經在使用異步,我會建議與async.each()替換fourthQueryfor()循環。

更新fourthQuery應該是這樣的:

function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){ 
 
    var size = array_nombresSecc.length; 
 
    var array_secciones = array_secciones; 
 
    var array_nombresSecc = array_nombresSecc; 
 

 
    var dishes = []; 
 

 
    pool.getConnection(function(err, connection) { 
 
     if(err) { 
 
      console.log(err); 
 
      callback(true); 
 
      return; 
 
     } 
 
     async.each(array_secciones, 
 
      function(item, itemCallback) { 
 
       // Function fun for each item in array_secciones 
 
       connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [item], 
 
        function(err, results2) { 
 
         if(err) { 
 
          console.log(err); 
 
          return itemCallback(true); 
 
         } 
 

 
         console.log("Result query 4 " + JSON.stringify(results2)); 
 
         dishes.push(results2); 
 
         console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[dishes.length-1])); 
 
         // this prints the result but only if it has a value over 2 
 
         return itemCallback(); 
 
        }); 
 
      }, 
 
      function(err) { 
 
       // Function run after all items in array are processed or an error occurs 
 
       console.log("I'm sending " + dishes); // this logs an empty array 
 
       callback(null, dishes, array_nombresSecc); 
 
      }); 
 
    }); // pool 
 
};

或者,你可以使用async.map(),它處理收集最終回調的結果,因此不依賴於dishes變量。

+0

感謝您的回覆..!我堅持我的循環,這是正確的。請看看這個,jmcgriz的答案幫了我很多。你也建議使用push,所以我相信它非常相似。 – Alan

相關問題