2017-02-26 4 views
1

Mein Problem ist, wenn ich Array von Benutzern bekomme und versuchen, async jedes starten es jedes sqlRequest starten und nicht eins nach dem anderen schieben Array.SQL-Abfrage mit Async jede

Es sollte sqlRequest 1 nach 1, und nicht alle von jedem Benutzer sqlRequest und der Push in einem Array tun. Hier

ist ein asynchroner jeder

function getUserFavCat(params, callback) { 
    var usersArrayCat = []; 
    async.each(params, function (user, cb) { 
    sqlRequest("SELECT b_cat.title, b_cat.id FROM dbo.Students st INNER JOIN dbo.SaleView sv ON sv.userId = st.id INNER JOIN dbo.KEY_BrandcategoryToSale b_key ON b_key.saleId = sv.saleId INNER JOIN dbo.BrandCategories b_cat ON b_cat.id = b_key.brandCategoryId WHERE st.id = " + user.id, function (err, result) { 
     if (!result) { 
     //console.error("NO FAVOURITE CATEGORY FOR USER " + JSON.stringify(user)) 
     } else if (result.length == 0) { 
     //console.error("NO FAVOURITE CATEGORY FOR USER " + JSON.stringify(user)) 
     } else { 
     user.favouriteCat = utils.takeMostRepeatingObj(result); 
     usersArrayCat.push(user); 
     } 
     cb(); 
    }) 
    }, function() { 
    callback(null, usersArrayCat) 
    }); 
}; 

Hier wird die SQL-Abfrage:

function sqlRequest (sqlQuery, callback) { 
    var connection = new sql.Connection(sql_conf, function (err) { 
    if (err){ 
     console.log(err) 
    } else { 
     var request = new sql.Request(connection); 
     request.query(sqlQuery, function(err, result) { 
     console.log(result) 
     if(err){ 
      console.error(err) 
     } else if(!result){ 
      console.error("NO RESPONSE SQL QUERY") 
     } else { 
      callback(null, result); 
      connection.close(); 
     } 
     }) 
    } 
    }); 
    connection.on('error', function(err) { 
    console.log(err); 
    }); 
}; 
+1

Nicht mit Ihrer Frage verbunden, aber bauen Sie Ihre Abfragen nicht so - Sie sind ein Loch zu SQL Injection opens. –

+0

aber wie sollte ich eine Schleife mit SQL-Abfragen ausführen? –

+0

Sorry, ich habe diesen Teil 'WHERE st.id =" + user.id' gemeint. Verketten Sie Ihre Strings nicht. Egal welche Bibliothek Sie verwenden, Sie sollten parametrisierte Abfragen erstellen. Machen Sie das. " –

Antwort

1

Verwendung async.eachLimit die nicht zu begrenzen. der Anfrage

function getUserFavCat(params, callback) { 
    var usersArrayCat = []; 
    console.log(`length of array ${params.length}`) 
         // 1 here means 1 request at a time 
    async.eachLimit(params, 1, function (user, cb) { 
     sqlRequest("SELECT b_cat.title, b_cat.id FROM dbo.Students st INNER JOIN dbo.SaleView sv ON sv.userId = st.id INNER JOIN dbo.KEY_BrandcategoryToSale b_key ON b_key.saleId = sv.saleId INNER JOIN dbo.BrandCategories b_cat ON b_cat.id = b_key.brandCategoryId WHERE st.id = " + user.id, function (err, result) { 
      if (!result) { 
       //console.error("NO FAVOURITE CATEGORY FOR USER " + JSON.stringify(user)) 
      } else if (result.length == 0) { 
       //console.error("NO FAVOURITE CATEGORY FOR USER " + JSON.stringify(user)) 
      } else { 
       user.favouriteCat = utils.takeMostRepeatingObj(result); 
       usersArrayCat.push(user); 
       cb(); 
      } 
     }) 
    }, function (err) { 
     if (err) return callback(err); 
     callback(null, usersArrayCat) 
    }); 
}; 
0

diesen Trick Versuchen von async.map mit und drücken Sie für jeden Rückruf zu einem Array. Dann können Sie async.parallel verwenden Sie die Callback-Ergebnisse für den Erfolg Benutzer heraus zu filtern und schieben Sie es auf usersArrayCat Arrays

function getUserFavCat(params, callback) { 
    var usersArrayCat = [], callbackArrays = []; 
    async.map(params, function (user, cb) { 
    callbackArrays.push(function (cb) { 
     sqlRequest("SELECT b_cat.title, b_cat.id FROM dbo.Students st INNER JOIN dbo.SaleView sv ON sv.userId = st.id INNER JOIN dbo.KEY_BrandcategoryToSale b_key ON b_key.saleId = sv.saleId INNER JOIN dbo.BrandCategories b_cat ON b_cat.id = b_key.brandCategoryId WHERE st.id = " + user.id, function (err, result) { 
     if (!result) { 
     user.status = '99'; // error status 
     cb(null, user); 
     } else if (result.length == 0) { 
     user.status = '99'; // error status 
     cb(null, user); 
     } else { 
     user.favouriteCat = utils.takeMostRepeatingObj(result); 
     user.status = '00'; //success status 
     cb(null, user); 
     } 
    }); 
    }, function(err, results) { 
    // comes here after all individual async calls have completed 
    // check errors; array of results is in data 
    cb(null, results) 
    }); 

    async.parallel(callbackArrays, function (err, results) { 
     results.forEach (function (elem, ind) { 
     if (elem.status == '00') { 
      usersArrayCat.push(elem); 
     } 
     }); 
    }); 
}; 
+0

Nein Das Problem ist, dass es nicht Schritt für Schritt geht, sondern erst nach jedem Benutzer, der die Abfrage ausführt, zum Rückruf zurückkehrt –