简体   繁体   English

如何使用node.js和Mongodb在Javascript中实现异步功能?

[英]How should I implement asynchronous function in Javascript with node.js and Mongodb?

So far I have seen that there are setTimeout() , process.nextTick(function) for asynchronous function however I have no clue as to how to use it. 到目前为止,我已经看到异步函数有setTimeout()process.nextTick(function) ,但是我不知道如何使用它。 I have tried on my code since I need a asynchronous function right now but it will have Can't set headers after they are sent. 我已经尝试了我的代码,因为现在需要异步函数,但是Can't set headers after they are sent.

This is my code: 这是我的代码:

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';

var updateRecord = function(db, req, callback) {
db.collection('documents').updateMany({ 'Item Description': 
req.body.itemDescrip }, {
    $set: { 'Issued QTY': req.body.issueQty }
}, function(err, results) {
    if (err) return callback(err);
    console.log('Done');
    console.log(results);
    var cursor = db.collection('documents').find({
        'Item Description': req.body.itemDescrip,
        'Issued QTY': req.body.issueQty
    });
    var temp = [];
    cursor.each(function(err, doc) {
        if (err) {
            return callback(err);
        } else{
        console.log('Successfully queried');
        console.log(doc);
        temp.push(JSON.stringify(doc));
        }
    });
    callback(null, temp);
});
};

 module.exports = {
    postCollection: function(req, res) {
    var issueQty = req.body.issueQty;
    var itemDescrip = req.body.itemDescrip;
    MongoClient.connect(url, function(err, db) {
        if(err) {
          res.send(err);
          res.end();
          db.close();
          return;
        }
        updateRecord(db, req, function(err, doc) {
            if(err){
              res.send(err);
            }
            else{
              //setTimeout(function(){
                  res.send(doc);
            //},2000);
            }
            res.end();
            db.close();
        });

    });
 }
}

Basically I am trying to implement an asynchronous function such that it will execute the updateRecord first before sending a response down below as right now without the setTimeout , all I get it [] due to executing both simultaneously. 基本上,我正在尝试实现一个异步函数,使其首先执行updateRecord然后立即在下面发送响应,而现在没有setTimeout ,由于同时执行这两个命令,我得到了它[] This is for my web api which I am testing via postman. 这是针对我正在通过邮递员进行测试的Web API。 Any help is appreciated, thanks! 任何帮助表示赞赏,谢谢!

Update: Finally it worked! 更新:终于成功了! However my output has \\ included in it which is rather weird since I did not put \\ in the db. 但是我的输出中包含\\ ,这很奇怪,因为我没有在数据库中输入\\ This is according to Roman Maksimov code below. 这是根据下面的Roman Maksimov代码编写的。

[
  "{\"_id\":\"18A\",\"Inventory for NTA SAM Cards\":\"\",\"Item Description\":\"Auresys EZL Prod\",\"Corrupted QTY\":\"\",\"Closing QTY\":\"100\",\"Remarks\":\"\",\"Opening QTY\":\"1000\",\"Issued QTY\":\"100\"}",
  "{\"_id\":\"20\",\"Inventory for NTA SAM Cards\":\"\",\"Item Description\":\"Auresys EZL Prod\",\"Corrupted QTY\":\"\",\"Closing QTY\":\"100\",\"Remarks\":\"\",\"Opening QTY\":\"1000\",\"Issued QTY\":\"100\"}",
  "null"
]

Seems your are do it under the Node.js (Am I right?). 看来您是在Node.js下执行的(我对吗?)。 From your desciription it's not clear what are you really want to reach. 根据您的描述,您还不清楚您真正想要达到什么目标。 But, obviously, you can't send a body to a response since you have ended it (from this point the response is already sent to the client and, of course, it's not possible to write to it). 但是,显然,自从结束响应后,您就无法将其发送给响应了(从这一点开始,响应已经发送给客户端了,当然,不可能对其进行写操作)。 Try this: 尝试这个:

updateRecord(db, req, function(err, doc) {
    if(err){
        res.send(err);
        res.end();
    } else {
        setTimeout(function(){
            res.send(doc);
            res.end();
        }, 2000);
    }
    db.close();
});

cursor.each is asynchronous, so, having the callback inside it may achieve unexpected results. cursor.each是异步的,因此在其中包含回调可能会达到意外的结果。

An easier way to achieve what you want is to remove the each function from the cursor and use the toArray method of mongodb. 实现所需功能的一种更简单的方法是从游标中删除each函数,然后使用mongodb的toArray方法。 Add the final callback inside the toArray callback 在toArray回调中添加最终的回调

var cursor = db.collection('documents').find({
  'Item Description': req.body.itemDescrip,
  'Issued QTY': req.body.issueQty
}).toArray(function(err, docs) {
  if (err) {
    return callback(err);
  }
  return callback(null, docs)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM