sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan håndteres tilbagekald i en for-løkke (Node.JS)

Dette problem betegnes som "tilbagekaldshelvede" .Der er masser af andre tilgange som f.eks. at bruge Promise og Async biblioteker, du finder.

Jeg er mere begejstret for den indfødte >async ES7 vil bringe, som du faktisk kan begynde at bruge i dag med transpiler-biblioteket Babel .

Men langt den enkleste tilgang, jeg har fundet, er følgende:Du fjerner de lange tilbagekaldsfunktioner og definerer dem udenfor.

router.route('/report') // the REST api address
    .post(calling_a_POST)

function calling_a_POST(req, res) {
    ...
    var data = "";
    https.get(url, function callback(response) {
        ...
        response.on("end", response_on_end_callback); // --> take out
        response.on("error", console.error);
    });
}

function response_on_end_callback() {                 // <-- define here
    ...
    for (var i = 0; i < length; i++) {
        var report = new Report(array.pop());
        ...
        Report.find({ id: report['id'] })
              .count(Report_find_count_callback);     // --> take out
    };
    res.json({
        message: 'Grabbed Report'
    });
}

function Report_find_count_callback(err, count) {     // <-- define here
    ...
    if (count == 0) {
        report.save(function(err) {                   // !! report is undefined here
            console.log('saved');
            if (err)
                res.send(err);                        // !! res is undefined here
        });
    }
}

En advarsel er, at du ikke vil være i stand til at få adgang til alle variabler inden for det, der plejede at være tilbagekaldet, fordi du har taget dem ud af anvendelsesområdet.

Dette kunne løses med en slags "afhængighedsindsprøjtning" for at videregive de nødvendige variabler.

router.route('/report') // the REST api address
    .post(calling_a_POST)

function calling_a_POST(req, res) {
    ...
    var data = "";
    https.get(url, function callback(response) {
        ...
        response.on("end", function(err, data){       // take these arguments
            response_on_end(err, data, res);          // plus the needed variables
        });
        response.on("error", console.error);
    });
}

function response_on_end(err, data, res) {  // and pass them to function defined outside
    ...
    for (var i = 0; i < length; i++) {
        var report = new Report(array.pop());
        ...
        Report.find({ id: report['id'] })
            .count(function(err, count){
                Report_find_count(err, count, report, res);  // same here
            });
    };
    res.json({                                        // res is now available
        message: 'Grabbed Report'
    });
}

function Report_find_count(err, count, report, res) {        // same here
    ...
    if (count == 0) {
        report.save(function(err) {                   // report is now available
            console.log('saved');
            if (err)
                res.send(err);                        // res is now available
        });
    }
}

Jeg er klar over, at jeg lavede en fejl her:

function calling_a_POST(req, res) {
    ...
    var data = "";
    https.get(url, function callback(response) {
        ...
        //sponse.on("end", function(err, data){
        response.on("end", function(err){ // data shouldn't be here
            response_on_end(err, data, res);
        });
        response.on("error", console.error);
    });
}

Et andet problem, jeg kunne forudse, som faktisk måske ikke opstår her, men som alligevel ville være bedre at tale om. data variabel, da det er en streng, som er en primitiv type i modsætning til et objekt, er den "bestået af værdi". Flere oplysninger

Det er bedre at pakke variablen ind i et objekt og videregive objektet, fordi objekter i javascript altid "passeres ved reference".

function calling_a_POST(req, res) {
    ...
    // var data = ""; // 
    var data_wrapper = {};
    data_wrapper.data = {};                                // wrap it in an object
    https.get(url, function callback(response) {
        ...
        response.on("data", function(chunk){
            data_wrapper.data += chunk.toString() + "";   // use the dot notation to reference
        });
        response.on("end", function(err){ 
            response_on_end(err, data_wrapper, res);      // and pass that object
        });
        response.on("error", console.error);
    });
}

function response_on_end_callback(err, data_wrapper, res) {
    var data = data_wrapper.data;                         // later redefine the variable
    ...
    for (var i = 0; i < length; i++) {
        var report = new Report(array.pop());
        ...


  1. MongoDB tælle kommando

  2. ClusterControl - Alle funktionernes højdepunkter og forbedringer fra 2017

  3. Mongo hvordan man $lookup med DBRef

  4. Distinct() kommando brugt med skip() og limit()