NodeJs在函数内初始化数组

时间:2016-07-02 16:57:36

标签: javascript node.js

我决定在我的nodejs项目中使用把手,所以对于索引页面,我想收集与帖子,页面,类别等相关的所有信息。

我有一个从数据库返回帖子的函数,如下所示;

exports.getPosts = function(req, res){

    Posts.find({}, function(err, posts) {
        var postsMap = {};

        if (err){
            res.status(400);
        }
        else{

            posts.forEach(function(post) {
              postsMap[post._id] = post;
            });

            res.jsonp(postsMap);
        }
    });
};

我想将该功能更改为以下原型;

function getPosts(req, res){
        var posts = [
                {
                    "url": "#",
                    "title": "home!",
                    "content": "home desc"
                },
                {
                    "url":"#2",
                    "title": "about",
                    "content": "about desc)" 
                }
            ]

    return posts;                    
}

我尝试过类似下面的代码,但是posts数组未初始化并返回undefined;

function getPosts(req, res){
    var posts = [];
    Posts.find({}, function(err, posts) {
        var postsMap = {};
        if (err){
            res.status(400);
        }
        else{
            posts.forEach(function(post) {
              postsMap[post._id] = post;
            });
           posts.push(postsMap);
        }
    });
    return posts;
}

我该如何处理这个问题?

2 个答案:

答案 0 :(得分:1)

在最后一段代码中,传递给Posts.find的函数在函数返回后才会运行

执行顺序为(见评论):

function getPosts(req, res){
    var posts = []; //// 1
    Posts.find({}, function(err, posts) {
        var postsMap = {}; //// 3
        if (err){
            res.status(400);
        }
        else{
            posts.forEach(function(post) {
              postsMap[post._id] = post;
            });
           posts.push(postsMap);
        }
    });
    return posts; // 2
}

这是因为Javascript是异步的,不会等待Post.find完成对数据库的调用。相反它会继续运行,稍后会调用function(err, posts)

通常要解决此问题,我们会为您的函数提供回调。您的代码可以重构为:

function getPosts(callback){ // Note that i removed res, req from this as it is good practice to separate out request handling from data fetching. Instead I moved it to the usage function mentioned later
    Posts.find({}, function(err, posts) {
        var postsMap = {};
        if (err){
            callback(err);
        }
        else{
            posts.forEach(function(post) {
              postsMap[post._id] = post;
            });
            callback(null, postsMap);
        }
    });
}

使用getPosts时,您可以执行以下操作:

function otherFunction(req, res){
    getPosts(function(err, postsMap){
         // This will start running once getPosts is done

         if(err)
             res.status(400);
         else
            res.jsonp(postsMap);
    })

    // This runs almost immediately and before getPosts is done
}

答案 1 :(得分:-1)

如果我理解,您想将Post.find()函数放入results变量,是吗?

问题1:你的回调有两个参数,第二个是posts

这创建了一个仅在回调中有效的变量,因此您无法访问getPosts()函数中的变量。

您所做的功能只是返回一个空数组,因为您无法访问它。

问题2:您尝试同步返回某个值但是您正在使用异步函数。

这是一个应该有效的示例代码:

function getPosts(req, res, callback) {
    var glob_posts = [];

    Posts.find({}, function(err, posts) {
        var postsMap = {};

        if(err)
            res.status(400);
        else {
            posts.forEach(function(post) {
              postsMap[post._id] = post;
            });

            glob_posts.push(postsMap);
            callback(glob_posts);
        }
    });
}

你可以通过这种方式使用这个功能:

getPosts(req, res, function(posts) {
    // The 'posts' variable contains current posts
});

我希望能帮到你:)。