簡體   English   中英

Node.js-通過回調插入MongoDB

[英]Node.js - Inserting into MongoDB with a callback

我正在嘗試使用asyncwaterfall方法將一些數據插入MongoDB集合中,以確保一切按正確的順序進行。 最初,我的數據以錯誤的順序插入到MongoDB中,經過一段時間我才意識到這是因為我的insert異步運行,所以我無法保證以正確的順序保存數據。

所以這是我的async.waterfall

async.waterfall([
    function(callback) {
      request.get(apiUrl, function(error, response, body) {
        if (!error && response.statusCode == 200) {
          data = JSON.parse(body);
          callback(error, data.items);
        }
      });
    },
    function(data, callback) {
      removeInvalidItems(data);
      var items = convertToObj(data);
      callback(null, items);
    },
    function(items, callback) {
      console.log(items);
      // Insert to collection here
    }
], function (err, result) {
    // do something here
});

因此,在瀑布的最后一個功能上,我已記錄了要控制台的items ,並且它以正確的順序顯示數據。 所以現在,我要做的就是將數據插入到我的集合中,然后在回調中關閉連接,然后從瀑布中移出到最終function 很容易吧? 好吧,這就是我現在正在嘗試的方法:

  MongoClient.connect(config.db, function(err, db) {
    if (err) {
      console.log(err);
    } else {
      console.log("Connected correctly to server");

      db.collection('items').insert(items, function(err, result) {
        if (err) {
          console.log(err);
        }
        db.close();
        callback(null, 'done');
      });
    }
  });

db.close()callback(null, 'done')應該在收到回調后關閉連接並移出瀑布。 但是我似乎得到的只是RangeError: Maximum call stack size exceeded 我已經嘗試了所有可以想到的方法,但無法將此插入與回調一起使用並移出瀑布。

有人可以幫忙嗎?

這個項目集合的大小是多少? 它可以超過調用堆棧的大小嗎? 要運行當前大小,請執行以下操作:

node --v8-options | grep -B0 -A1 stack_size

默認大小是492 kB(對於32位)和984 kB(對於64位)。

要增加調用堆棧的大小,請嘗試使用參數啟動節點:

node --max-stack-size={your-desired-size-in-bytes}

考慮到節點可能沒有時間清除每個瀑布回調之間的調用棧。 嘗試在nextTick上運行回調:

async.waterfall([
    function(callback) {
      request.get(apiUrl, function(error, response, body) {
        if (!error && response.statusCode == 200) {
          data = JSON.parse(body);
          callback(error, data.items);
        }
      });
    },
    function(data, callback) {
      removeInvalidItems(data);
      var items = convertToObj(data);
      process.nextTick(function() {   // callback on next tick
          callback(null, items);
      });
    },
    function(items, callback) {
      console.log(items);
      // Insert to collection here
    }
], function (err, result) {
    // do something here
});

應該為async.waterfall()的每個任務調用所有回調。 僅在您的第一個瀑布任務成功的情況下才調用它……而在第三個瀑布任務中根本沒有調用它。

這兩個調用沒有回調:

removeInvalidItems(data);
items = convertToObj(data);

所以我假設它們不是異步的。 而且由於它們不是異步的,因此您不必將它們作為async.waterfall()的單獨任務。 因此,這是修改后的代碼(我假設您的數據轉換正確):

async.waterfall([
    function(callback) {
        request.get(apiUrl, function(error, response, body) {
            var data;
            if (!error && response.statusCode == 200) {
                data = JSON.parse(body);
                return callback(null, data.items);
            }
            callback(error || response); // error or statusCode !== 200
        });
    },
    function(data, callback) {
        var items;

        // There is no callback for these, so I'm assuming they are not asynchronous
        removeInvalidItems(data);
        items = convertToObj(data);

        MongoClient.connect(config.db, function(err, db) {
            if (err) {
                console.log(err);
                return callback(err);
            }
            console.log("Connected correctly to server");
            db.collection('items').insert(items, function(err, result) {
                if (err || !result) {
                    console.log(err);
                    db.close();
                    return callback(err || {message: 'There is a problem inserting.'});
                }
                db.close();
                callback(null);
            });
        });
    }
], function (err, result) {
    if (err) {
        console.log(err);
    } else {
        console.log('done');
    }
});

我已經找到了答案,以我自己的問題在這里 問題是,當我將數據批量插入MongoDB時,我收到了Maximum call stack size exceeded錯誤。 根據名為User的Mongoose模式,我在運行db.collection('something').insert(data, function()....時使用的數據數組是Users數組,因此該data數組中的每個項目都是創建為var item = new User({});顯然,MongoDB不喜歡這樣。我認為這是插入數據的正確方法,因為在生產中這就是我將如何使用數據(使用User對象) 。

為了糾正這個問題,我簡單地更換var item = new User({})var item = {}這樣我只是創建一個新的JavaScript對象。 這樣可以很好地工作,並且可以按照正確的順序將數據插入數據庫中,而不會出錯。 多虧寫了其他答案的人們,我才使用這些答案來修復和改善回調!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM