2017-03-14 7 views
0

Ich habe diese Schleife für ein paar Tage rätselhaft gemacht und komme nicht ganz zu dem, was ich brauche.Neue Elemente an Objekte in Array anfügen

I Schleife über meine Array von Suchergebnissen (mdb_results) und von jedem Objekt extrahiert ein .name als _search Begriff in einer Google CSE Bildersuche zu verwenden.

Th CSE gibt ein weiteres Array (cse) zurück, das ich an das Objekt anhängen möchte, von dem ich den _search Begriff (mdb_results[i]) extrahiert habe.

router.get('/json', function(req, res, next) { 
var ImageSearch = require('node-google-image-search'); 
MongoClient.connect(url, function(err,db){ 
    db.collection('mycatalog') 
    .find({$text: {$search:"FOO" }}) 
    .toArray(function(err, mdb_results){  
     for (var i=0; i<mdb_results.length; i++){   
      var _search = mdb_results[i].name ; 

      ImageSearch(_search, function(cse){ 

       // How to add cse.img to mdb_results[i].images ?? 
       // mdb_results[i].images = cse; 
       // gives undefined 

      },0,2); 
     }; 
     res.send(mdb_results); 
     }); 
    }); 
}); 

Meine erste mdb_results sieht wie folgt aus.

[{"name":"FOO"},{"name":"FOOOO"}] 

Ich versuche, so etwas wie dies zu erreichen,

[{"name":"FOO", 
    "images":[{"img1":"http://thumbnail1"},{"img2":"http://thumbnail2"}] 
}, 
{"name":"FOOOO", 
    "images":[{"img1":"http://thumbnaila"},{"img2":"http://thumbnailb"}] 
}] 

Kann mir jemand zeigen, wie dies zu erreichen?

Dank

Antwort

1

Das Problem ist, dass Sie eine asynchrone Operation erwar synchron arbeiten:

router.get('/json', function(req, res, next) { 
var ImageSearch = require('node-google-image-search'); 
MongoClient.connect(url, function(err,db){ 
    db.collection('mycatalog') 
    .find({$text: {$search:"FOO" }}) 
    .toArray(function(err, mdb_results){  
     for (var i=0; i<mdb_results.length; i++){   
      var _search = mdb_results[i].name ; 
      // This search is asynchronous, it won't have returned by the time 
      // you return the result below. 
      ImageSearch(_search, function(cse){ 

       // How to add cse.img to mdb_results[i].images ?? 
       // mdb_results[i].images = cse; 
       // gives undefined 

      },0,2); 
     }; 
     // At this point, ImageSearch has been called, but has not returned results. 
     res.send(mdb_results); 
     }); 
    }); 
}); 

Du wirst Versprechen müssen verwenden oder die async Bibliothek.

Hier ist ein Beispiel:

router.get('/json', function(req, res, next) { 
var ImageSearch = require('node-google-image-search'); 
MongoClient.connect(url, function(err,db){ 
    db.collection('mycatalog') 
    .find({$text: {$search:"FOO" }}) 
    .toArray(function(err, mdb_results){ 
     // async.forEach will iterate through an array and perform an asynchronous action. 
     // It waits for you to call callback() to indicate that you are done 
     // rather than waiting for it to execute synchronously. 
     async.forEach(mdb_results, function (result, callback) { 
      ImageSearch(result.name, function(cse){ 
       // This code doesn't get executed until the network call returns results. 
       result.images = cse; 
       // This indicate that you are done with this iteration. 
       return callback(); 
      },0,2); 
     }, 
     // This gets call once callback() is called for each element in the array, 
     // so this only gets fired after ImageSearch returns you results. 
     function (err) { 
      res.send(mdb_results); 
     }); 
    }); 
}); 
+0

Dies funktioniert und ich nahm deine Antwort - Danke. Würde es Ihnen etwas ausmachen, ein wenig darüber nachzudenken, was mit "cb" los ist? Obwohl es funktioniert, habe ich Probleme zu verstehen, was passiert. – Colin

+0

Ich habe den Beitrag aktualisiert, um zu versuchen, zu erarbeiten. Das Verständnis, wie Callbacks in NodeJS funktionieren, ist entscheidend, um zu verstehen, was hier vor sich geht. Der Rückruf wird verwendet, um anzuzeigen, dass Sie fertig sind. – EmptyArsenal

+0

Danke für die Anmerkungen. Ich kämpfe immer noch mit 'return callback()', was ein Aufruf an sich selbst zu sein scheint? Wir geben 'Callback' in die umschließende Funktion und rufen sie dann ohne irgendeine Funktionsdefinition für 'Rückruf' auf. Wenn die Antwort für einen Kommentar zu komplex ist, können Sie mir eine Ressource empfehlen, in der ich mich weiterbilden kann? – Colin