从javascript回调中获取数据的正确方法

时间:2012-05-25 00:51:48

标签: node.js express

我正在将一个api服务器从一个普通的nodejs脚本转换为一个使用express框架的脚本,以获得更好的稳定性。

我的一个问题是你无法从回调中返回值,因为原始代码已经继续......

var _json = api.query();

不知何故,我们更喜欢.query()返回最终的结果对象,所以我们可以将它串化为JSON,然后将其传递给渲染器,就像这样:

// Render the display
res.render('posts-resp', {
    title: res.app.settings.app_title,
    _use_Callback: _use_Callback,
    json: _json
});

但是,db查询使用回调来处理查询结果,因此无法返回这样的值。在原始版本中, db脚本处理渲染最终视图,但我不希望它们像这样捆绑在一起。

query: function(){

    db.query( this._buildQuery(), function(err, res){
        if(err){ throw err; }
        res.fetchAll(function(err, rows){
            if(err){ throw err; }
            db.query('SELECT FOUND_ROWS() as num, UNIX_TIMESTAMP() as query_timestamp;', function(err, cnt_res){
                if(err){ throw err; }
                cnt_res.fetchAll(function(err, cnt_rows){
                    var obj = {
                        results:rows,
                        total_results:cnt_rows[0].num,
                        current_offset:self.offset,
                        query_timestamp:cnt_rows[0].query_timestamp
                    };
                    // ... ?
                });
            });
        });
    });
}

如何正确获取数据并将其传递给渲染系统?

1 个答案:

答案 0 :(得分:1)

JavaScript是一种非常灵活的语言。您实际上不需要直接将视图绑定到数据库代码,因为您可以使用函数作为包装器来抽象视图代码并使其与数据库逻辑分开。

当需要异步逻辑时,回调可以是一个非常强大的工具。我不确定这里是否需要它,但您仍然可以使用包装函数将视图代码与DB代码分开来封装视图逻辑:

查看代码的函数包装器:

function delegateToView(data) {

    // process data here before sending to view

    // Render the display
    res.render('posts-resp', {
        title: res.app.settings.app_title,
        _use_Callback: _use_Callback,
        json: _json
    });
}

回调函数调用的数据库代码:

 db.query('SELECT FOUND_ROWS() as num, UNIX_TIMESTAMP() as query_timestamp;', function(err, cnt_res){
                if(err){ throw err; }
                cnt_res.fetchAll(function(err, cnt_rows){
                    var obj = {
                        results:rows,
                        total_results:cnt_rows[0].num,
                        current_offset:self.offset,
                        query_timestamp:cnt_rows[0].query_timestamp
                    };
                    // ... ?

                    //call your delegator here and pass in any needed data.
                     // this keeps the actual view code separate.
                    delegateToView(obj);


                });
            });

现在,如果您的视图代码需要更改,则无需触及数据库代码中的任何逻辑或回调函数中的任何逻辑。祝你好运!