NodeJS无法使用嵌套查询创建数组

时间:2014-01-16 23:09:02

标签: javascript node.js mongodb

成功查询Mongodb以获取新闻列表后,对于附有链接的新闻,我搜索数据库中的链接详细信息,但在我将它们设置在修改后的新闻对象中后,我无法将其推送到数组。为什么会这样?

var newsarray = []
for(i=0;i<newsfound.length;i++){
    if(!newsfound[i].link._id){
        newsarray.push(newsfound[i])
    } else {
        var tempnew = newsfound[i];
        db.findOne('links',{'_id':tempnew.link._id},function(err,linkdetails){
            if(err){
                console.log(err)
            } else {
                tempnew.linkdetails = linkdetails;
                newsarray.push(tempnew)
            }
        })
    }
}
console.log(newsarray)

这样的结果是没有包含新闻的链接的数组,或者如果我尝试对原始新闻进行一些更改而没有添加详细信息的数组。

1 个答案:

答案 0 :(得分:1)

您不能在for循环中使用异步函数。原因是for循环在执行任何回调之前都会被执行,因此范围变得混乱。

您应该使用递归函数(自我调用),这将阻止在上一次结束之前的下一次异步调用。

var i = 0;
function fn() {
    // your logic goes here,
    // make an async function call or whatever. I have shown async in a timeout.
    setTimeout(function () {
        i += 1;    
        if (i < newsfound.length) {
            fn();
        } else {
            // done
            // print result
        }
    });

}

<强>更新

对于您的用例,

var newsarray = []
var i = 0;

function done() {
    // done, use the result
    console.log(newsarray);
}

function fn() {
    if (!newsfound[i].link._id) {
        newsarray.push(newsfound[i]);
        i += 1;
        if (i < newsfound.length) {
            fn();
        } else {
            done();
        }
    } else {
        var tempnew = newsfound[i];
        db.findOne('links', {'_id':tempnew.link._id}, function(err, linkdetails){
            if(err){
                console.log(err)
            } else {
                tempnew.linkdetails = linkdetails;
                newsarray.push(tempnew);
                i += 1;
                if (i < newsfound.length) {
                    fn();
                } else {
                    done();
                }
            }
        })
    }
}