异步javascript最佳实践

时间:2013-12-26 22:24:09

标签: javascript asynchronous express

使用node.js / express.js,这里是我面对异步代码的典型问题的一个例子(函数使用2分贝调用呈现请求页面):

exports.index = function(req, res){
    res.render('index', {
        data1: getData1(),
        data2: getData2()
    });
};

以下是一个函数的样子:

function getData1() {
    var assets = db.get("assets");
    assets.find().on('success', function (docs) {
        // What to do ?
    });
}

我尝试使用async.js,这是一个非常有用的模块,但我仍然不知道如何处理这样的案例。

有人可以建议有关异步JavaScript编码的最佳实践的良好资源吗?

3 个答案:

答案 0 :(得分:1)

使用异步工作流程库,例如async

function getData1(done) {
    var assets = db.get('assets');
    assets.find().on('success', done);
}

function getData2(done) {
    var assets2 = db.get('assets2');
    assets2.find().on('success', done);
}

exports.index = function(req, res, next){
    async.parallel({
        d1: getData1,
        d2: getData2
    }, render);

    function render (err, data) {
        if (err) {
            return next(err);
        }

        res.render('index', {
            data1: data.d1,
            data2: data.d2
        });
    });
};

通过这种方式,您可以坚持整个Node包中的callback(err, result)样式,同时保持代码的理智和漂亮。 async提供了简化工作流程的方法。在这种情况下,我使用了async.parallel方法,它允许您同时运行任意数量的回调,然后在其他回调完成时运行作为第二个参数提供的函数。

答案 1 :(得分:0)

解决问题的一种方法是通过将回调函数传递给执行异步操作的函数来链接异步命令:

exports.index = function(req, res){
    getData1(function (data1) {
        getData2(function (data2) {
            res.render('index', {
                data1: data1,
                data2: data2
            });
        });
    });
};

function getData1(callback) {
    var assets = db.get("assets");
    assets.find().on('success', callback);
}
// Similarly for getData2

但是,嵌套回调很快就会变得无法管理。您可以命名函数来帮助解决这个问题:

exports.index = function(req, res){
    var data2Success = function (data1, data2) {
        res.render('index', {
            data1: data1,
            data2: data2
        });
    },
    data1Success = function (data1) {
        getData2(data2Success.bind(this, data1));
    };

    getData1(data1Success);
};

答案 2 :(得分:0)

我通常会做以下其中一项:

1)阻止您的通话:

exports.index = function(req, res){
  //first call
  assets.getRecord(function (err, docs) {

    // 2nd call
    assets.getSomeOtherRecord(function (err, otherDocs) {
        res.render('index', {
          data1:docs,
          data2: otherDocs
        });
    );

  });

};

如果您的代码很简单,并且您不介意一个接一个地运行这些代码,那么这就足够了。如果那些不适用,我使用方法#2:

2)使用async.js或Q,如此处的其他答案所示。

了解异步的资源:
- http://net.tutsplus.com/tutorials/javascript-ajax/managing-the-asynchronous-nature-of-node-js/
- http://www.sebastianseilund.com/nodejs-async-in-practice