2013-10-10 3 views
2

Я пытаюсь использовать библиотеку async, но я не знаю, как переписать обратный вызов ад в реальном мире. Меня особенно интересует метод серии в сочетании с коммуникацией с некоторым существующим драйвером. Может ли кто-нибудь переписать следующий исходный код, используя метод async.js series? Это взято из this link.Пример реального мира метода асинхронной библиотеки caolan

Я не привязан к 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(); 
      }); 
      } 
     }); 
     }); 
    }); 
    }); 
}); 
+0

Также посмотрите на [ 'step'] (https://github.com/creationix/step) и [' streamline.js'] (https: // GitHub. com/Sage/streamlinejs) для некоторых идей. – robertklep

ответ

2

Вы можете начать с определения каждого из обратных вызовов в этой вложенной системе в качестве функций. Таким образом, основная идея заключается в том, а не делать

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

вы

action(data, namedCallback) 

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

Вещи следует отметить об этой реализации

  • Переменные, которые вы хотите поделиться, определенные в рамках всех функций (см. var db и var 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(); 
} 
3

Нечто подобное с 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(); 
})