MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как да обработваме обратни извиквания в for цикъл (Node.JS)

Този проблем се нарича "callback hell" .Има много други подходи като използването на Promise и Async библиотеки, които ще намерите.

Повече се вълнувам от родния async ES7 ще донесе, което всъщност можете да започнете да използвате днес с библиотеката на transpiler Babel .

Но най-простият подход, който открих, е следният:Изваждате дългите функции за обратно извикване и ги дефинирате навън.

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
        });
    }
}

Едно предупреждение е, че няма да имате достъп до всички променливи вътре в това, което преди беше обратното извикване, защото сте ги извадили от обхвата.

Това може да бъде решено с нещо като обвивка на "инжектиране на зависимости", която да предава необходимите променливи.

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
        });
    }
}

Разбирам, че направих грешка тук:

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);
    });
}

Друг проблем, който можех да предвидя, който всъщност може да не възникне тук, но все пак би било по-добре да поговорим за него. data променлива, тъй като това е низ, който е примитивен тип за разлика от обект, той се „предава по стойност“. Повече информация

По-добре е да обвиете променливата в обект и да предадете обекта, защото обектите в javascript винаги се „предават по референция“.

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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. mongodb как да върна списък със стойност само от заявка за намиране

  2. Премахване на записи в масив, съдържащи празен масив

  3. как да структурирам съставен индекс в mongodb

  4. MongoError напишете EPIPE” в инсталацията на Parse-Server

  5. Операция за актуализиране на Mongodb вътре в подмасив