【问题标题】:Real world example of caolan's async library series methodcaolan 的异步库系列方法的真实示例
【发布时间】:2013-10-17 17:37:54
【问题描述】:

我正在尝试使用async 库,但我不知道如何在现实世界的示例中重写回调地狱。我对串联方法以及与某些现有驱动程序的通信特别感兴趣。有人可以使用 async.js 系列方法重写以下源代码吗?取自this link

我不喜欢 MongoDb。如果有人将其他一些回调地狱示例改写为异步系列,那就太好了。

除了异步库之外,我还对任何替代解决方案感兴趣。但同样 - 在该解决方案中重写此示例(或显示其他完整示例),以便我们可以查看真实代码并进行比较。

var MongoClient = require('../lib/mongodb').MongoClient
  , format = require('util').format;

var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : 27017;

console.log("Connecting to " + host + ":" + port);
MongoClient.connect(format("mongodb://%s:%s/node-mongo-examples?w=1", host, port), function(err, db) {
  db.dropDatabase(function(err, result) {

    var collection = db.collection('test');
    // Erase all records from the collection, if any
    collection.remove({}, function(err, result) {
      // Insert 3 records
      for(var i = 0; i < 3; i++) {
        collection.insert({'a':i}, {w:0});
      }

      collection.count(function(err, count) {
        console.log("There are " + count + " records in the test collection. Here they are:");

        collection.find().each(function(err, item) {
          if(item != null) {
            console.dir(item);
            console.log("created at " + new Date(item._id.generationTime) + "\n")
          }

          // Null signifies end of iterator
          if(item == null) {
            // Destory the collection
            collection.drop(function(err, collection) {
              db.close();
            });
          }
        });
      });
    });
  });
});

【问题讨论】:

标签: javascript node.js async.js


【解决方案1】:

与 async.series 类似(代码未经测试,仅供参考):

var async = require('async') 
  , MongoClient = require('../lib/mongodb').MongoClient
  , format = require('util').format;

var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : 27017;
var collection, db
console.log("Connecting to " + host + ":" + port);
async.series([
    // Connect to DB
    function(callback) {
        var connectionString = format("mongodb://%s:%s/node-mongo-examples?w=1", host, port)
        MongoClient.connect(connectionString, function(err, ref) {
            if (ref) db = ref
            callback(err, ref)
        })
    },
    // Drop DB
    function(callback) {
        db.dropDatabase(callback)
    },
    // Erase all records from the collection, if any
    function(callback) {
        collection = db.collection('test');
        collection.remove({}, callback)
    },
    // Insert 3 records
    function(callback) {
        async.each(new Array(3), function(cb) {
            collection.insert({'a':i}, {w:0}, cb);
        }, callback)
    },
    //Check records count
    function(callback) {
        collection.count(function(err, count) {
            if (err) return callback(err)
            console.log("There are " + count + " records in the test collection. Here they are:");
            callback(err, count)
        })
    },
    //Indicate items
    function(callback) {
        collection.find({}, function(err, items) {
            items.forEach(function(item) {
                if(item == null) return
                console.dir(item);
                console.log("created at " + new Date(item._id.generationTime) + "\n")
            })
            callback(err, items)
        })
    },
    function(callback) {
        collection.drop(callback)
    }
], function(error, results) {
    // disconnect from DB
    error && console.error(error)
    db && db.close();
})

或者像这样(混合瀑布和系列方法,没有全局变量):

    var async = require('async') 
  , MongoClient = require('../lib/mongodb').MongoClient
  , format = require('util').format;

var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : 27017;

console.log("Connecting to " + host + ":" + port);
async.waterfall({
    // Connect to DB
    db: function(callback) {
        var connectionString = format("mongodb://%s:%s/node-mongo-examples?w=1", host, port)
        MongoClient.connect(connectionString, callback)
    },
    // Drop DB
    collection: function(db, callback) {
        db.dropDatabase(function(err, result) {
            var collection = db.collection('test');
            callback(err, collection)
        })
    },
    collModifications: function(collection, callback) {
        async.series([
        // Erase all records from the collection, if any
            function(callback) {
                collection.remove({}, callback)
            },
            // Insert 3 records
            function(callback) {
                async.each(new Array(3), function(cb) {
                    collection.insert({'a':i}, {w:0}, cb);
                }, callback)
            },
            //Check records count
            function(callback) {
                collection.count(function(err, count) {
                    if (err) return callback(err)
                    console.log("There are " + count + " records in the test collection. Here they are:");
                    callback(err, count)
                })
            },
            //Indicate items
            function(callback) {
                collection.find({}, function(err, items) {
                    items.forEach(function(item) {
                        if(item == null) return
                        console.dir(item);
                        console.log("created at " + new Date(item._id.generationTime) + "\n")
                    })
                    callback(err, items)
                })
            },
            function(callback) {
                collection.drop(callback)
            }
        ], callback)
    }
}, function(error, results) {
    // disconnect from DB
    error && console.error(error)
    results && results.db && results.db.close();
})

【讨论】:

    【解决方案2】:

    您可以首先将这个嵌套系统中的每个回调定义为函数。所以基本思想是代替做

    action(data, function (err, value) { if (err) { ... } ... })
    

    你会的

    action(data, namedCallback)
    
    function namedCallback(err, value) {
         if (err) { ... }
         ....
         nextAction(value, nextNamedCallback)
    }
    

    关于这个实现你应该注意的事情

    • 您要共享的变量在所有函数的范围内定义(请参阅var dbvar collection
    • 在此实现中,所有函数都是回调,要使用系列实现,您需要将函数拆分为执行动作的函数,而不是处理动作的函数完成
    • 您应该正确处理回调中的错误情况
    var MongoClient = require('../lib/mongodb').MongoClient
        , format = require('util').format;
    
    var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ?
      process.env['MONGO_NODE_DRIVER_HOST'] :
      'localhost';
    
    var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ?
        process.env['MONGO_NODE_DRIVER_PORT'] :
        27017;
    
    console.log("Connecting to " + host + ":" + port);
    MongoClient.connect(
        format("mongodb://%s:%s/node-mongo-examples?w=1", host, port)
        onConnect)
    
    
    var db
    var collection
    
    function onConnect(err, _db) {
        db = _db
        db.dropDatabase(onDrop);
    }
    
    function onDrop(err, result) {
        collection = db.collection('test');
    
        // Erase all records from the collection, if any
        collection.remove({}, onRemove);
    }
    
    function onRemove(err, result) {
          // Insert 3 records
        for(var i = 0; i < 3; i++) {
            collection.insert({ 'a': i }, { w: 0 });
        }
    
        collection.count(onCount)
    }
    
    function onCount(err, count) {
        console.log("There are",
            count,
            "records in the test collection. Here they are:");
    
        collection.find().each(onFind);
    }
    
    function onFind(err, item) {
        if (item != null) {
            console.dir(item);
            console.log("created at " + new Date(item._id.generationTime) + "\n")
        }
    
        // Null signifies end of iterator
        if (item == null) {
            // Destory the collection
            collection.drop(onEnd)
        }
    }
    
    function onEnd(err, item) {
        db.close();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      相关资源
      最近更新 更多