Laatste tijd ben ik fan van NodeJS. Althans een beginende fan. Met Node JS moet je namelijk asynchroon denken, dat is wel moeilijk. Met een andere programmeertaal wordt alle code achter elkaar uitgevoerd, maar met node JS wordt alles tegelijkertijd uitgevoerd en moet je met events werken tot een bepaalde taak klaar is.
Ik zal je een voorbeeldje geven, in de onderstaande snippet wil ik bijv. een afbeelding downloaden van een externe bron en deze lokaal opslaan. Bekijk de onderstaande code goed..
var data = new Stream();
// download een afbeelding
request.get({url: item.image_url},function(err,response,body) {
// doe hier iets met de response
})
on('data', function(chunk) {
// voor de simpliciteit ff jpg 🙂
file_type = "jpg";
// push de data naar de array
data.push(chunk);
}).on('end',function(){
// wanneer de events klaar zijn schrijf data weg in een file
fs.writeFile("filename.jpg", data.read(),function(wErr,wSucc){
});
});
Als ik deze uitvoer dan wordt er een afbeelding netjes gedownload:). Maar wat als we meer afbeeldingen willen downloaden?Werkt de code dan nog steeds?
Meerdere afbeeldingen downloaden
De code werkt wel, maar onvoorspelbaar. Als we de bovenstaande code in een loop zouden plaatsen zoals dit:
for(var i =0; i<5000; i++) {
var data = new Stream();
// download een afbeelding
request.get({url: item.image_url},function(err,response,body) {
// doe hier iets met de response
})
on('data', function(chunk) {
// voor de simpliciteit ff jpg
file_type = "jpg";
// push de data naar de array
data.push(chunk);
}).on('end',function(){
// wanneer de events klaar zijn schrijf data weg in een file
fs.writeFile(i+".jpg", data.read(),function(wErr,wSucc){
});
});
}
Dan kan het voorkomen de sommige afbeeldingen niet worden gedownload. Oftwel je ziet wel een filename, maar hier zit geen data in! Dit komt omdat 5000x een request wordt gedaan om de afbeelding te downloaden. Dit kan je server waarschijnlijk niet aan :(. Je krijgt dan corrupte afbeeldingen / lege afbeelding etc..
We moeten de library async gebruiken om dit op te lossen. Dit stelt ons in staat om een soort van synchroon te werken, maar let op, de code is nog steeds asynchroon. Deze lib zorgt ervoor dat de code toch achter elkaar wordt uitgevoerd, en niet 5000 x tegelijkertijd.
Zie de onderstaande snippet, je moet wel de library async downloaden “npm –save install async”. Neem dan de volgende snippet over en plaats je business logic hierin.
var page = 1,
lastPage = 5000;
async.whilst(function () {
return page <= lastPage;
},
function (next) {
// BUSINESS LOGIC HIERZO
// de code wordt dan nu sync uitgevoerd (een soort van om het beter te begrijpen)
// dit zorgt ervoor dat er geincrement wordt
page++;
// next zorgt ervoor dat de volgende request uitgevoerd mag worden
next();
});
},
function (err) {
// All things are done!
});