关于Nodejs的异步控制:async 与 eventproxy

关于Nodejs的异步控制:async 与 eventproxy

myTest 里的数据:{id:1,name:‘a’},{id:2,name:‘b’},{id:3,name:‘c’}; 我想对idArr中的每一个id通过get查找返回list或者result,get方法里又是异步(或者get里面会更加复杂),这么写只能查到id:3, 求教大神怎么解决

var mongodb = require('./db');
function asyncTest() {
    var idArr = [1, 2, 3];
    /*
     eventproxy
     */
    var Eventproxy = require('eventproxy');
    var ep = new Eventproxy();
    ep.after('find', idArr.length, function (list) {
        console.log('this is the final')
        console.log(list)
    });
    for (var i = 0; i < idArr.length; i++) {
        console.log('for loop'+i)
        get(idArr[i], function (err, results) {
            ep.emit('find', results);
            console.log('result'+results)
        });
    }

    /*
     async
     */
    var async = require('async');
    async.map(idArr,function(id,cb){
        get(id,function(err,results){
            if(err){

            }
            cb(null,results);
        })
    }),function(err,results){
        if(err){

        }
        console.log('result'+results);
    }
}
function get (req,cb){
    console.log(req+'find');
    mongodb.close();
    mongodb.open(function(err,db){
        if(err){
        }
        console.log(req+'find col');
        db.collection('myTest',function(err,collection){
            if(err){
                console.log(err)
            }
            collection.find({id:req}).toArray(function(err,doc){
                if(err){
                    console.log(err);
                }
                console.log(doc)
                cb(err,doc)
            })
        })
    })
}
asyncTest();

3 回复

标题:关于Nodejs的异步控制:async 与 eventproxy

内容: 在Node.js中处理异步操作时,asynceventproxy 是两个非常有用的工具。本文将通过一个具体的例子来说明如何使用它们来处理一系列异步操作。

假设我们有一个数组 idArr,其中包含多个ID,我们需要通过这些ID查询数据库,并获取相应的结果。为了确保所有查询都完成后再处理最终结果,我们可以使用 eventproxyasync 来实现。

首先,让我们看看如何使用 eventproxy

var mongodb = require('./db');
var Eventproxy = require('eventproxy');

function asyncTest() {
    var idArr = [1, 2, 3];

    var ep = new Eventproxy();
    ep.after('find', idArr.length, function (list) {
        console.log('this is the final')
        console.log(list)
    });

    for (var i = 0; i < idArr.length; i++) {
        get(idArr[i], function (err, results) {
            if (err) {
                console.error(err);
            } else {
                ep.emit('find', results);
            }
        });
    }
}

function get (req, cb){
    console.log(req + ' find');
    mongodb.open(function(err, db){
        if (err) {
            return cb(err);
        }
        db.collection('myTest', function(err, collection){
            if (err) {
                return cb(err);
            }
            collection.find({id: req}).toArray(function(err, doc){
                if (err) {
                    return cb(err);
                }
                console.log(doc);
                cb(null, doc);
            });
        });
    });
}

asyncTest();

在这个例子中,我们使用了 eventproxyafter 方法来确保所有查询完成后才执行回调函数。ep.after('find', idArr.length, ...) 表示当 find 事件被触发 idArr.length 次后,才会执行最终的回调函数。

接下来,我们来看看如何使用 async 库来实现相同的功能:

var mongodb = require('./db');
var async = require('async');

function asyncTest() {
    var idArr = [1, 2, 3];

    async.map(idArr, function(id, cb) {
        get(id, function(err, results) {
            if (err) {
                return cb(err);
            }
            cb(null, results);
        });
    }, function(err, results) {
        if (err) {
            console.error(err);
        } else {
            console.log('final result:', results);
        }
    });
}

// get 函数保持不变

在这个例子中,我们使用了 async.map 方法来并行处理所有的查询操作。async.map 会为每个元素调用给定的函数,并将结果收集到一个数组中。最后的回调函数会在所有查询完成后被调用,并传递最终的结果数组。

这两种方法都可以有效地处理异步操作,选择哪种方法取决于具体的需求和个人偏好。


这种问题首先debug下;我对mongodb不是很了解,但是看着一会儿close,一会儿又open,不造会不会问题…

在这个问题中,asyncTest函数需要依次处理多个异步操作,并确保所有操作完成后才能执行最终的操作。你可以使用EventProxyasync库来实现这一点。

使用 EventProxy

EventProxy 是一个用于简化异步回调管理的库。after 方法用于等待多个事件完成后再执行回调。

var mongodb = require('./db');
var Eventproxy = require('eventproxy');

function asyncTest() {
    var idArr = [1, 2, 3];
    var ep = new Eventproxy();

    ep.after('find', idArr.length, function (list) {
        console.log('this is the final');
        console.log(list);
    });

    for (var i = 0; i < idArr.length; i++) {
        get(idArr[i], function (err, results) {
            if (err) return;
            ep.emit('find', results);
        });
    }
}

function get (req, cb) {
    console.log(req + ' find');
    mongodb.open(function(err, db) {
        if (err) return;
        db.collection('myTest', function(err, collection) {
            if (err) return;
            collection.find({ id: req }).toArray(function(err, doc) {
                if (err) return;
                console.log(doc);
                cb(err, doc);
            });
        });
    });
}

asyncTest();

使用 async

async 库提供了多种方法来处理异步操作,比如 map 方法可以并行或顺序地处理数组中的每个元素。

var mongodb = require('./db');
var async = require('async');

function asyncTest() {
    var idArr = [1, 2, 3];

    async.map(idArr, function (id, cb) {
        get(id, function (err, results) {
            if (err) return cb(err);
            cb(null, results);
        });
    }, function (err, results) {
        if (err) return;
        console.log('result', results);
    });
}

function get (req, cb) {
    console.log(req + ' find');
    mongodb.open(function(err, db) {
        if (err) return;
        db.collection('myTest', function(err, collection) {
            if (err) return;
            collection.find({ id: req }).toArray(function(err, doc) {
                if (err) return;
                console.log(doc);
                cb(err, doc);
            });
        });
    });
}

asyncTest();

总结

  • EventProxy 适合处理复杂的异步流程控制,特别是在需要多个异步操作的结果时。
  • async 提供了更结构化的异步控制方法,适合处理数组中的每个元素。

以上两种方法都能确保所有异步操作完成后再执行最终的操作。

回到顶部