New to async programming so I just can't figure how to do this:
$results = [];
products.forEach(function (product) {
// 1. Search ...
google(keyword, function (err, res) {
if (err) console.error(err)
for (var i = 0; i < res.links.length; ++i) {
var result = res.links[i];
var obj = {
title: res.links[i].title,
href: res.links[i].href,
description: res.links[i].description
}
results.push(obj); // 2. store each result in results Array
}
}, processData); // 3. send all results to processData when done
// 5. NOW, itereate further ...
});
function processData(results) {
console.log('processing data');
// 4. save results to DB
}
Since the process requires making HTTP requests, collecting data and then saving to DB which all takes time, so I don't want forEach to advance to the next element until one is done.
Answer
Since the forEach is synchronous and the request is asynchronous, there is no way to do it exactly as you describe. What you can do however is to create a function that handles one item from the docs array and removes it, then when you're done processing, go to the next:
var results;
var productsToProcess;
MongoClient.connect( 'mongodb://localhost:27017/suppliers', function ( err, db ) {
assert.equal( null, err );
var findDocuments = function ( db ) {
var collection = db.collection( 'products' );
collection.find( {
$and: [ {
"qty": {
$gt: 0
}
}, {
"costex": {
$lte: 1000.0
}
} ]
}, {
"mpn": 1,
"vendor": 1,
"_id": 0
} ).limit( 1 ).toArray( function ( err, products ) {
assert.equal( err, null );
productsToProcess = products;
getSearching();
db.close();
} );
}
findDocuments( db );
} );
function getSearching() {
if ( productsToProcess.length === 0 ) return;
var product = productsToProcess.splice( 0, 1 )[0];
var keyword = product[ 'vendor' ] + ' "' + product[ 'mpn' ] + '"';
google( keyword, function ( err, res ) {
if ( err ) console.error( err )
for ( var i = 0; i < res.links.length; ++i ) {
var result = res.links[ i ];
var obj = {
title: res.links[ i ].title,
href: res.links[ i ].href,
description: res.links[ i ].description
}
results.push( obj );
}
}, processData );
}
function processData( results ) {
MongoClient.connect( 'mongodb://localhost:27017/google', function ( err, db ) {
assert.equal( null, err );
// insert document to DB
var insertDocuments = function ( db, callback ) {
// Get the documents collection
var collection = db.collection( 'results' );
// Insert some documents
collection.insert( results, function ( err, result ) {
assert.equal( err, null );
console.log( "Document inserted" );
callback( result );
db.close();
} );
}
insertDocuments( db, getSearching );
} );
}
EDIT
Moved the products from the database to the productsToProcess
variable and changed the getSearching()
to no longer require a parameter.
No comments:
Post a Comment