【问题标题】:node.js, testing a mongodb save and loadnode.js,测试一个 mongodb 保存和加载
【发布时间】:2012-01-22 21:55:43
【问题描述】:

也许我只是无法弄清楚回调性,但我想不出一种方法来测试 node.js 中的保存和加载。

我的测试是这样的:

vows.describe('Saving').addBatch({
    'Single item can be saved':{
        topic:function () {
            myStore.saveItems(1, [{id:3,name:'squat'}]);
            myStore.getItems(1, this.callback);
        },
        'saved item is returned by getItems':function (err, items) {
            assert.equal(items.length, 1);
            assert.equal(items[0].deviceId, 1);
            assert.equal(items[0].id, 3);
        }
    }
}).export(module);

正在测试中:

exports.saveItems = function (deviceId, items) {
    var itemsCollection = db.collection('items');

    itemsCollection.find({deviceId:deviceId}).toArray(function (err, existingItems) {
        _.each(items, function (item) {
            item['deviceId'] = deviceId;
            var existingItem = _.find(existingItems, function (existingItem) {
                return existingItem.id === item.id
            });
            if (typeof(existingItem) === 'undefined') {
                itemsCollection.save(item);//callback here?
            } else {
            }
        });
    });
};

exports.getItems = function (deviceId, callback) {
    var itemsCollection = db.collection('items');
    itemsCollection.find({deviceId:deviceId}).toArray(callback);
};

有没有一种方法可以将回调传递给saveItems,这样在所有 mongo 保存完成之前不会调用getItems

【问题讨论】:

    标签: javascript node.js mongodb vows


    【解决方案1】:

    试试这个:)

    vows.describe('Saving').addBatch({
        'Single item can be saved':{
            topic:function () {
              var topicThis = this;
              // NEW: having a callback here
              myStore.saveItems(1, [{id:3,name:'squat'}], function(err, results){
                  myStore.getItems(1, topicThis.callback);    
              });
            },
            'saved item is returned by getItems':function (err, items) {
                assert.equal(items.length, 1);
                assert.equal(items[0].deviceId, 1);
                assert.equal(items[0].id, 3);
            }
        }
    }).export(module);
    
    // https://github.com/caolan/async
    var async = require('async');
    // NEW: having a callback here
    exports.saveItems = function (deviceId, items, cb) {
        var itemsCollection = db.collection('items');
    
        itemsCollection.find({deviceId:deviceId}).toArray(function (err, existingItems) {
            var tasks = [];
            // here you are iterating over each item, doing some work, and then conditionally doing an async op
            _.each(items, function (item) {
                item['deviceId'] = deviceId;
                var existingItem = _.find(existingItems, function (existingItem) {
                    return existingItem.id === item.id
                });
                if (typeof(existingItem) === 'undefined') {
                    // so this is async, b/c it's talking to mongo
                    // NEW: add it to our list of tasks, when are later run in parallel
                    tasks.push(function(nextTask){
                        itemsCollection.save(item, nextTask);
                    });
                }
            });
            // NEW: run it all in parrallel, when done, call back
            async.parallel(tasks, function(err, results) {
                cb(err, results);
            })
        });
    };
    

    【讨论】:

    • 哈,节省了我在#Node.js 上发布答案和引用 dtrejo 的时间。
    【解决方案2】:

    使用 node.js mongo db 驱动: http://mongodb.github.com/node-mongodb-native/api-articles/nodekoarticle1.html

    插入和更新函数都是用回调定义的。我只使用更新函数,因为它也可以用作插入(如果下面的第一个参数没有获取任何记录)。

    itemsCollection.update({_id: itemId}, item, {upsert:true, safe:true}, function (err, result) {
      // callback here
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-14
      • 2017-07-17
      • 2014-01-22
      • 2021-05-22
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多