mongodb 在节点 js eachOf 循环中查询

mongodb query inside node js eachOf loop

我想在应该同步的 eachOf 循环中添加嵌套的数据库查询。尝试了很多组合,但在 foreach 循环内部没有任何效果。

   async.eachOf(nc.virtual_devices, function (vd) {
         ///////// This code work fine /////////////
        var domain = extractDomain(vd.api_url);
        vd.raw_api_ip = vd.api_ip;
        vd.api_ip = getProxiedPath(vd.api_ip);
        vd.raw_api_url = vd.api_url;
        vd.api_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.api_url.split(domain)[1];
          // Path to websocket notifications
        vd.ws_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.notification_base_uri;

     //// THIS CODE IS NOT FINE //////////////
        if (nc.type === 'XXX'){

            var promise = new Promise (function (resolve,reject) {

            console.log("********XX VD TYPE **********");
            console.log(JSON.stringify(vd));
            console.log("VD ID VALUE IS ", vd.id);
            var newID = (vd.id).replace(/\d_/, "");
            console.log("VD ID VALUE IS ", newID);

            var _idofSubgroup;
            var labeltoSearch = nc.type + ' ' + nc.version;
            pattern = "/^" + newID + "/i";
            test = _idofSubgroup;
            pattern = newID;
            console.log(pattern);

            db.collection('subgroups').findOne({label: labeltoSearch}, function (err, result) {
                console.log(result._id);
                _idofSubgroup = result._id;

                db.collection('exploreposts').find({subgroup: result.id_}, {title: {"$regex": pattern}}).toArray(function (err, results) {
                    console.log(results);
                })
        });
        })
    }
  });

尝试了其中的承诺,但也很痛苦。 这是我试过的代码,但不能正常工作。任何建议将不胜感激。简单地说,我一直陷入回调地狱

   async.eachOf(nc.virtual_devices, function (vd) {
         ///////// This code work fine /////////////
        var domain = extractDomain(vd.api_url);
        vd.raw_api_ip = vd.api_ip;
        vd.api_ip = getProxiedPath(vd.api_ip);
        vd.raw_api_url = vd.api_url;
        vd.api_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.api_url.split(domain)[1];
          // Path to websocket notifications
        vd.ws_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.notification_base_uri;

     //// THIS CODE IS NOT FINE with promises also  //////////////
        if (nc.type === 'XXX'){

            var promise = new Promise (function (resolve,reject) {

            console.log("********XX VD TYPE **********");
            console.log(JSON.stringify(vd));
            console.log("VD ID VALUE IS ", vd.id);
            var newID = (vd.id).replace(/\d_/, "");
            console.log("VD ID VALUE IS ", newID);

            var _idofSubgroup;
            var labeltoSearch = nc.type + ' ' + nc.version;
            pattern = "/^" + newID + "/i";
            test = _idofSubgroup;
            pattern = newID;
            console.log(pattern);

            db.collection('subgroups').findOne({label: labeltoSearch}, function (err, result) {
                console.log(result._id);
                _idofSubgroup = result._id;
                resolve ({id_:_idofSubgroup,pattern1 : pattern});
            })
        });
        promise.then (function(result) {
            console.log(result.id_);
            console.log(result.pattern1);
                db.collection('exploreposts').find({subgroup: result.id_}, {title: {"$regex": result.pattern1}}).toArray(function (err, results) {
                    console.log(results);
                })
        },function (err){
            console.log (err);
       })


    }
  });

您似乎不需要使用 async.eachOf,但是 async.each() or async.eachSeries().

这是未经测试的,但它看起来像

async.eachSeries(nc.virtual_devices, function iteratee(vd, cb) {
    console.log('calling iteratee()')
    
    var domain = extractDomain(vd.api_url);
    vd.raw_api_ip = vd.api_ip;
    vd.api_ip = getProxiedPath(vd.api_ip);
    vd.raw_api_url = vd.api_url;
    vd.api_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.api_url.split(domain)[1];
     // Path to websocket notifications
    vd.ws_url = nconf.get('PROXIED_PATH_SCHEME') + vd.api_ip + vd.notification_base_uri;

    // skip the rest if type is XXX;
    // you need to explicitedly call the original callback i.e. cb
    // note the use of return to prevent execution of the rest of the code
    if (nc.type !== 'XXX')
        return cb(null); // or cb();

    console.log("********XX VD TYPE **********");
    console.log(JSON.stringify(vd));
    console.log("VD ID VALUE IS ", vd.id);
    var newID = (vd.id).replace(/\d_/, "");
    console.log("VD ID VALUE IS ", newID);

    // I have no idea what is going here
    var _idofSubgroup;
    var labeltoSearch = nc.type + ' ' + nc.version;
    var pattern = "/^" + newID + "/i";
    test = _idofSubgroup;
    pattern = newID;
    console.log(pattern);
    
    // we're going to use waterfall here as you have 2 async operations, where one is dependent on the other 
    async.waterfall([
        function getSubgroup(cb1) {
            console.log('calling getSubgroup')
            db.collection('subgroups').findOne({ label: labeltoSearch }, function (err, subgroup) {
                // if an error occurs, stop waterfall-loop
                // you do this by passing the error in the callback
                // again note the use of return here to prevent execution of the rest of the code
                if (err) return cb1(err);
                // pass the data to the next task
                cb1(null, subgroup, pattern);
            });
        },
        function getPosts(subgroup, pattern, cb2) {
            // we will only get here if the last task ^ went through
            console.log('calling getPosts')
            db.collection('exploreposts').find({ subgroup: subgroup._id, title: { $regex: pattern }}).toArray(function (err, posts) {
                // if an error occurs, stop waterfall-loop
                if (err) return cb2(err);
                // do something with posts
                console.log('posts', posts);
                // otherwise, keep going
                // since there are no more waterfall-tasks, waterfall ends
                cb2();
            });
        }
    ], function (err) {
        console.log('waterfall() done');
        // if an error occurred during the waterfall-loop, it will come down here
        // we will let the original callback i.e. cb deal with this error though
        if (err) return cb(err);
        // otherwise we're done
        // we will let the original callback know everything went well by calling it without any error
        cb();
    });
    
    // you could have also simply do
 // ], cb);
    

}, function (err) {
    console.log('eachSeries() done');
    // handle any error that came
    console.log(err);
    // send response
});

我特意为变量和函数命名,以便您有所了解。

如果有任何问题,请关注日志。