MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Cách xử lý các lệnh gọi lại trong vòng lặp for (Node.JS)

Sự cố này được gọi là "địa ngục gọi lại" .Có rất nhiều cách tiếp cận khác như sử dụng Promise Async thư viện bạn sẽ tìm thấy.

Tôi hào hứng hơn với async ES7 sẽ mang lại, mà bạn thực sự có thể bắt đầu sử dụng ngay hôm nay với thư viện chuyển tiếp Babel .

Nhưng cho đến nay, cách tiếp cận đơn giản nhất mà tôi đã tìm thấy là như sau:Bạn lấy ra các hàm gọi lại dài và định nghĩa chúng bên ngoài.

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

Một lưu ý là bạn sẽ không thể truy cập tất cả các biến bên trong những gì đã từng là lệnh gọi lại, bởi vì bạn đã đưa chúng ra khỏi phạm vi.

Điều này có thể được giải quyết bằng một trình bao bọc "phụ thuộc vào" các loại để chuyển các biến được yêu cầu.

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

Tôi nhận ra mình đã mắc lỗi ở đây:

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

Một vấn đề khác mà tôi có thể nhận thấy, thực sự có thể không phát sinh ở đây nhưng vẫn tốt hơn nên nói về mọi thứ. data biến, vì đó là một chuỗi là kiểu nguyên thủy không giống đối tượng, nó được "truyền theo giá trị". Thông tin thêm

Tốt hơn là nên bọc biến trong một đối tượng và chuyển đối tượng, vì các đối tượng trong javascript luôn được "truyền bằng tham chiếu".

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. So sánh các phần tử của mảng, loại bỏ phần tử có điểm thấp nhất

  2. Làm cách nào để biết ngày tạo bộ sưu tập MongoDB bằng trình điều khiển MongoDB C #?

  3. Tổng quan về MongoDB Atlas:Phần một

  4. Tổng hợp Mongodb với 2 bộ sưu tập

  5. Mô hình hóa dữ liệu MongoDB:bất kỳ hạn chế nào khi sử dụng nhiều cơ sở dữ liệu?