Javascript 多个Node.js回调的问题

Javascript 多个Node.js回调的问题,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我正试图解决我的一份工作中遇到的一个问题。所以基本上,这个请求从soundcloud获取我的曲目,我循环搜索结果并将数据放入mongodb集合中。这一切都很好,但现在我添加了另一个部分的网站,所以我需要从另一个收集一些额外的信息 我有一个轨道收集,和一个库存收集。轨迹id位于两个集合中,用于将附加轨迹数据与新拉入的轨迹关联那么我的问题是如何获取这些额外的曲目数据?下面我尝试通过mongoose的query.find()循环并注入数据,但循环不能一起工作。库存查询的回调将在一个for循环中运行,看

我正试图解决我的一份工作中遇到的一个问题。所以基本上,这个请求从soundcloud获取我的曲目,我循环搜索结果并将数据放入mongodb集合中。这一切都很好,但现在我添加了另一个部分的网站,所以我需要从另一个收集一些额外的信息

我有一个轨道收集,和一个库存收集。轨迹id位于两个集合中,用于将附加轨迹数据与新拉入的轨迹关联那么我的问题是如何获取这些额外的曲目数据?下面我尝试通过mongoose的query.find()循环并注入数据,但循环不能一起工作。库存查询的回调将在一个for循环中运行,看起来。。。我不太清楚那里发生了什么

我很确定,您也可以通过在模式中引用另一个集合中的文档来注入该文档。。。但我不确定如何让它工作。这显然是一个更好的解决方案,因为它不需要更多这样的代码

如果有人对我有任何建议,那就太好了

request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
        var o = 1;

        for(i=0; i < body.tracks.length; i++){
            var last = (i + 1);
            var track = body.tracks[i];

            if( track.sharing == 'public'){
                var invData;
                var obj;

                db.model('inventory').find({id:track.id}).exec(function(err,item){
                    //console.log(item[0]);
                    invData = item[0];


                });


                console.log(invData, obj);

                obj = new TracksModel({
                    id: track.id,
                    sharing:track.sharing,
                    uri:track.uri,
                    description:track.description,
                    created_at:track.created_at,
                    duration:track.duration,
                    title:track.title,
                    description:track.description,
                    order: o,
                    inventory_data: invData
                });





                o++;

                obj.save(function (err) {
                    if (!err) {
                        console.log('Track inserted successfully');
                    } else {
                        throw err;
                    }
                });

                if(last == body.length){
                    setTimeout(function(){
                        console.log("Automatically closing database connection after 5 seconds");
                        db.close();
                    }, 5000);
                }

            }

        }

} else {
    console.log('An error has occurred: ', error);
}
});
请求({
url:url,
json:true
},函数(错误、响应、正文){
如果(!error&&response.statusCode==200){
VarO=1;
对于(i=0;i
处理查询回调的方式是错误的。假设从“console.log(invData,obj);”开始的代码将在db.model.find之后立即执行。这不是回调的正确概念。如何将代码放入exec回调函数中。您可能需要使用闭包。 比如:

if (!error && response.statusCode === 200) {
    var o = 1;

    for(i=0; i < body.tracks.length; i++){
        var last = (i + 1);
        var track = body.tracks[i];

        if( track.sharing == 'public'){

            (function(track,last,o){

                var invData;
                var obj;

                db.model('inventory').find({id:track.id}).exec(function(err,item){
                    //console.log(item[0]);
                    invData = item[0];

                    console.log(invData, obj);

                    obj = new TracksModel({
                        id: track.id,
                        sharing:track.sharing,
                        uri:track.uri,
                        description:track.description,
                        created_at:track.created_at,
                        duration:track.duration,
                        title:track.title,
                        description:track.description,
                        order: o,
                        inventory_data: invData
                    });

                    obj.save(function (err) {
                        if (!err) {
                            console.log('Track inserted successfully');
                        } else {
                            throw err;
                        }
                    });

                    if(last == body.length){
                        setTimeout(function(){
                            console.log("Automatically closing database connection after 5 seconds");
                            db.close();
                        }, 5000);
                    }
                });
            }(track,last,o);    

            o++;
        }

    }
if(!error&&response.statusCode==200){
VarO=1;
对于(i=0;i
}

试试这个:

var utils = require('restberry-utils');

var Inventory = mongoose.model('Inventory');
var Track = mongoose.model('Track');

request({
    url: url,
    json: true
}, function (error, response, body) {
    if (error || response.statusCode !== 200) {
        console.log('An error has occurred: ', error);
        return;
    }
    utils.forEachAndDone(body.track, function(track, iter) {
        if (track.sharing !== 'public') {
            iter();
            return;
        }
        Inventory.findOne({ id: track.id }, function(err, item) {
            new Track({
                id: track.id,
                sharing: track.sharing,
                uri: track.uri,
                description: track.description,
                created_at: track.created_at,
                duration: track.duration,
                title: track.title,
                description: track.description,
                order: o,
                inventory_data: item,
            }).save(function(err) {
                if (err) {
                    throw err;
                } else {
                    console.log('Track inserted successfully');
                    iter();
                }
            })
        });
    }, function() {
        console.log('Done!');
        setTimeout(function() {
            console.log("Automatically closing database connection after 5 seconds");
            db.close();
        }, 5000);
    })
});

有趣!你觉得restberry的功能真的很有用吗?我喜欢让事情变得轻松,但如果这能让我的生活更轻松,我会毫不犹豫地把它放进去。谢谢你的回复!我仍在努力写这样的节点。我是restberry的作者,所以我认为它很有用;)forEachAndDone方法适用于需要循环遍历数组,然后在最后执行一些操作的情况,这对于回调来说总是很棘手的。这不是一个很难自己实现的方法,所以您可能会这样做,不想这样做,因为这个答案为什么我选择导入我经常使用的UTIL:)哦,很酷,是的,在node中让回调正常运行对我来说有点困难。。我去看看!谢谢@ShanRobertson很酷,很高兴我能帮上忙。请注意将此标记为正确答案:)那么
(函数(track,last,o){}(track,last,o);
的目的是什么呢?如果我正确理解exec,它会立即执行回调,在相同的
循环中执行
?谢谢您的回答!find命令是异步的